package com.yanqu.road.server.manager.douluodalu;

import com.yanqu.road.entity.DataStatus;
import com.yanqu.road.entity.activity.ActivityInfo;
import com.yanqu.road.entity.activity.douluodalu.*;
import com.yanqu.road.entity.activity.douluodalu.config.DouLuoDaLuConfig;
import com.yanqu.road.entity.activity.douluodalu.config.DouLuoDaLuEventInfo;
import com.yanqu.road.entity.activity.douluodalu.config.DouLuoDaLuRegionInfo;
import com.yanqu.road.entity.activity.douluodalu.data.DouLuoDaLuHelpRecordData;
import com.yanqu.road.entity.activity.douluodalu.data.DouLuoDaLuPatronsBattleData;
import com.yanqu.road.entity.activity.douluodalu.data.DouLuoDaLuTeamData;
import com.yanqu.road.entity.activity.douluodalu.data.DouLuoDaLuUserData;
import com.yanqu.road.entity.activity.douluodalu.enums.eDouLuoDaLuBuffType;
import com.yanqu.road.entity.activity.douluodalu.enums.eDouLuoDaLuEventType;
import com.yanqu.road.entity.activity.douluodalu.log.DouLuoDaLuBattleNoticeData;
import com.yanqu.road.entity.activity.douluodalu.log.DouLuoDaLuEventNoticeData;
import com.yanqu.road.entity.activity.douluodalu.log.PatronsBlood;
import com.yanqu.road.entity.activity.douluodalu.result.BuffCalResult;
import com.yanqu.road.entity.config.goods.GoodsInfo;
import com.yanqu.road.entity.enums.eActivityType;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eGoodsType;
import com.yanqu.road.entity.log.cross.LogDouLuoDaLuHunHuan;
import com.yanqu.road.entity.log.cross.LogDouLuoDaLuKill;
import com.yanqu.road.entity.log.cross.LogDouLuoDaLuScoreChange;
import com.yanqu.road.entity.log.cross.LogDouLuoDaLuTeam;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.entity.rank.yrank.UserYRank;
import com.yanqu.road.entity.union.activitygroup.UnionActivityGroup;
import com.yanqu.road.logic.activity.DouLuoDaLuLogic;
import com.yanqu.road.logic.bussiness.servercenter.ActivityBussiness;
import com.yanqu.road.logic.cross.CrossActivityTeamRankListModel;
import com.yanqu.road.logic.helper.RandomWeightConfigHelper;
import com.yanqu.road.logic.helper.UnionActivityGroupHelper;
import com.yanqu.road.logic.pb.DouLuoDaLuPb;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.pb.rank.RankProto;
import com.yanqu.road.server.CrossBaseServer;
import com.yanqu.road.server.manager.config.GoodsMgr;
import com.yanqu.road.server.manager.log.CrossAutoLogMgr;
import com.yanqu.road.server.manager.union.activitygroup.Cross2UnionActivityGroupMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.manager.yrank.CrossYRankCacheMgr;
import com.yanqu.road.server.manager.yrank.CrossYRankMgr;
import com.yanqu.road.server.manger.CrossUnionServerGroupMgr;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.pb.activity.douluodalu.DouLuoDaLuProto;
import com.yanqu.road.pb.worldmessage.WorldMessageProto;
import com.yanqu.road.server.TempCrossMgr;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.activity.ActivityMgr;
import com.yanqu.road.server.manager.activity.ActivityTeamRankMgr;
import com.yanqu.road.server.manager.douluodalu.impl.DouLuoDaLuBaseEventAction;
import com.yanqu.road.server.manger.TempCommonMgr;
import com.yanqu.road.message.YanQuMessage;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;
import org.apache.mina.util.ConcurrentHashSet;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

public class CrossDouLuoDaLuMgr extends TempCrossMgr {

    //    static Map<Integer, CrossDouLouDaLuActivity> activityMap = new ConcurrentHashMap<>();
    static Map<Integer, DouLuoActivityGroup> activityGroupMap = new ConcurrentHashMap<>();

    @Override
    public boolean init() throws Exception {
        return reload();
    }

    @Override
    public boolean reloadConfig() throws Exception {
        return true;
    }

    @Override
    public boolean reloadData() throws Exception {
        String nowTimeStr = DateHelper.getCurrentDateTimeString();
        List<Integer> activityTypeList = new ArrayList<>();
        activityTypeList.add(eActivityType.DouLuoDaLuActivity.getValue());
        Map<Integer, ActivityInfo> tempActivityInfoMap = ActivityBussiness.getOpenCrossRankActivityInfoMap(activityTypeList, nowTimeStr);
        for (ActivityInfo activityInfo : tempActivityInfoMap.values()) {
            Map<Integer, UnionActivityGroup> activityGroupMap = Cross2UnionActivityGroupMgr.getGroupMap(activityInfo.getActivityId());
            if (null != activityGroupMap) {
                for (UnionActivityGroup activityGroup : activityGroupMap.values()) {
                    if (activityGroup.getCrossServerId() == CrossBaseServer.getInstance().getServerId()) {
                        getActivity(activityInfo.getActivityId(), activityGroup.getGroupId());
                    }
                }
            }
        }
//        Map<Integer, CrossDouLouDaLuActivity> tempActivityMap = new ConcurrentHashMap<>();
//        for (Map.Entry<Integer, ActivityInfo> activityInfoEntry : ActivityMgr.getOpenCrossActivityMapByType(eActivityType.DouLuoDaLuActivity.getValue()).entrySet()) {
//            CrossDouLouDaLuActivity louDaLuActivity = new CrossDouLouDaLuActivity(activityInfoEntry.getKey());
////            louDaLuActivity.init();
//            tempActivityMap.put(activityInfoEntry.getKey(), louDaLuActivity);
//        }
//        activityMap = tempActivityMap;
        return true;
    }

    @Override
    public boolean stop() {
        return false;
    }

    @Override
    public boolean save() {
        for (DouLuoActivityGroup activityGroup : activityGroupMap.values()) {
            activityGroup.save();
        }

        return true;
    }

    public static DouLuoActivityGroup getActivityGroup(int activityId) {
        DouLuoActivityGroup activityGroup = activityGroupMap.get(activityId);
        if (activityGroup == null) {
            synchronized (activityGroupMap) {
                activityGroup = activityGroupMap.get(activityId);
                if (activityGroup == null) {
                    activityGroup = new DouLuoActivityGroup(activityId);
                    activityGroupMap.put(activityId, activityGroup);
                }
            }
        }
        return activityGroup;
    }


    public static CrossDouLouDaLuActivity getActivityOrNull(int activityId, int groupId) {
        DouLuoActivityGroup activityGroup = activityGroupMap.get(activityId);
        if (activityGroup == null) {
            return null;
        }
        return activityGroup.getActivityOrNull(groupId);
    }

    public static CrossDouLouDaLuActivity getActivity(int activityId, int groupId) {
        if (groupId == UnionActivityGroupHelper.NO_GROUP_ID) {
            return null;
        }
        ActivityInfo activityInfo = CrossDouLuoDaLuActivityMgr.getActivityInfo(activityId);
        if (activityInfo == null) {
            return null;
        }

        DouLuoActivityGroup activityGroup = getActivityGroup(activityId);
        CrossDouLouDaLuActivity activity = activityGroup.getActivity(groupId);
        return activity;
    }

    /**
     * 获取玩家数据
     */
    public static DouLuoDaLuProto.DouLuoDaLuGetUserDataRespMsg.Builder getUserMsg(int activityId, long playerId, long allPatronsEarn, UserBaseInfo userBaseInfo, List<DouLuoDaLuUserPatrons> userPatrons
            , List<DouLuoDaLuProto.DouLuoDaLuUserMallInfo> mallInfoList, boolean isEntry) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, playerId);

        DouLuoDaLuProto.DouLuoDaLuGetUserDataRespMsg.Builder respMsg = DouLuoDaLuProto.DouLuoDaLuGetUserDataRespMsg.newBuilder();
        CrossDouLouDaLuActivity douLouDaLuActivity = getActivity(activityId, groupId);
        if (null == douLouDaLuActivity) {
            respMsg.setRet(GameErrorCode.E_ACTIVITY_NO_FOUND);
            return respMsg;
        }

        DouLuoDaLuUserData userData = douLouDaLuActivity.getUser(playerId, userBaseInfo, allPatronsEarn, userPatrons);
        userData.setEntry(isEntry);
        douLouDaLuActivity.refreshUserEnergy(userData, false);
        respMsg.setUserData(buildUserEntity(douLouDaLuActivity, userData));
        // 队伍信息
        DouLuoDaLuTeamData team = douLouDaLuActivity.getAllTeamMap().get(userData.getTeamId());
        if(team != null){
            boolean showApplyList = team.getCaptainId() == playerId;
            respMsg.setTeamInfo(buildTeamEntity(douLouDaLuActivity, team, showApplyList));
        }
        if(userData.isEntry()) {
            if(userData.getLeaveTip() != null && userData.getLeaveTip().getLeaveStatus() > 0){
                // 如果有离队信息，设完值重置信息
                respMsg.setLeaveInfo(buildLeaveInfoEntity(douLouDaLuActivity, userData));
                userData.setLeaveTip(null);
            }
            if(userData.getEnemyTipList() != null && userData.getEnemyTipList().size() > 0){
                // 被击杀 仇人信息
                List<DouLuoDaLuEnemyTip> list = userData.getEnemyTipList();
                for (int i = 0; i < list.size(); i++) {
                    respMsg.addEnemyInfo(buildEnemyEntity(douLouDaLuActivity, list.get(i)));
                }
                userData.setEnemyTipList(new ArrayList<>());
            }
        }
        if(userData.getTeamId() > 0){
            douLouDaLuActivity.syncBaseInfoToServer(userData);
        }
        respMsg.addAllMallInfo(mallInfoList);
        respMsg.setRet(0);
        return respMsg;
    }

    private static DouLuoDaLuProto.DouLuoDaLuUserDataTemp.Builder buildUserEntity(CrossDouLouDaLuActivity douLouDaLuActivity, DouLuoDaLuUserData userData) {
        DouLuoDaLuProto.DouLuoDaLuUserDataTemp.Builder builder = DouLuoDaLuProto.DouLuoDaLuUserDataTemp.newBuilder();
        builder.setTeamId(userData.getTeamId());
        builder.addAllUnlockRegionId(userData.getOpenRegionList());
        builder.setEnergy(userData.getEnergy());
        builder.setEnergyLastTime(userData.getEnergyLastTime());
        builder.setBlood(userData.getBlood());
        builder.setTotalBlood(userData.getTotalBlood());
        builder.setHunLi(userData.getHunLi());
        builder.setRegionId(userData.getRegionId());
        builder.setScoreOne(userData.getScore());
        builder.setLastLeaveTeam(userData.getLastLeaveTime());
        builder.setAllPatronsEarn(userData.getAllPatronsEarn());
        builder.setPatronsNum(userData.getPatronsMap().size());
        for (Map.Entry<Integer, Long> longEntry : userData.getApplyJoinTeamMap().entrySet()) {
            builder.addApplyJoinTeamIdList(longEntry.getKey());
        }
        DouLuoDaLuPatronsBattleData battleData = douLouDaLuActivity.getBattleDataMap().get(userData.getUserId());
        if(battleData != null){
            builder.setScoreTwo(battleData.getScore());
        }
        builder.setRankOne(getUserRank(douLouDaLuActivity, userData, eGamePlayerEventType.DouLuoDaLuPhaseOneUserScoreCrossRank.getValue()));
        builder.setRankTwo(getUserRank(douLouDaLuActivity, userData, eGamePlayerEventType.DouLuoDaLuPhaseTwoUserScoreCrossRank.getValue()));
        builder.setLastCreateTeam(userData.getLastCreateTime());
        DouLuoDaLuProto.DouLuoDaLuEventDataTemp.Builder eventBuilder = DouLuoDaLuProto.DouLuoDaLuEventDataTemp.newBuilder();
        eventBuilder.setAttackStatus(userData.getEvent().getStatus());
        eventBuilder.setEventId(userData.getEvent().getEventId());
        eventBuilder.setLastAttackTime(userData.getEvent().getAttackTime());
        if(userData.getEvent().getEnemyUserId() > 0){
            DouLuoDaLuUserData enemy = douLouDaLuActivity.getAllUserMap().get(userData.getEvent().getEnemyUserId());
            eventBuilder.setTargetBlood(enemy.getBlood());
            eventBuilder.setTargetTotalBlood(enemy.getTotalBlood());
            eventBuilder.setUserId(userData.getEvent().getEnemyUserId());
        }else {
            eventBuilder.setTargetTotalBlood(userData.getEvent().getTotalBlood());
            eventBuilder.setTargetBlood(userData.getEvent().getBlood());
        }
        eventBuilder.setMonsterId(userData.getEvent().getMonsterId());
        eventBuilder.setEventId(userData.getEvent().getEventId());
        if(userData.getEvent().getEnemyUserId() > 0){
            DouLuoDaLuUserData enemy = douLouDaLuActivity.getAllUserMap().get(userData.getEvent().getEnemyUserId());
            if(enemy != null){
                eventBuilder.setTargetInfo(PlayerBasePb.parsePlayerBaseTempMsg(enemy.getUserBaseInfo()));
            }
        }
        builder.addAllHunHuan(DouLuoDaLuPb.parseUserItemTemp(userData.getHunHuanMap()));
        builder.addAllBuff(DouLuoDaLuPb.parseUserItemTemp(userData.getBuffMap()));
        builder.addAllBox(DouLuoDaLuPb.parseUserItemTemp(userData.getBoxMap()));
        builder.addAllEventDone(DouLuoDaLuPb.parseUserItemTemp(userData.getFinishEventMap()));
        //当前标记
        DouLuoDaLuHelpRecordData helpRecordData = userData.getCurrentHelpRecordData();
        if(helpRecordData != null){
            DouLuoDaLuProto.DouLuoDaLuCurrentHelpEntity.Builder helpBuilder = DouLuoDaLuProto.DouLuoDaLuCurrentHelpEntity.newBuilder();
            helpBuilder.setRecordId(helpRecordData.getId());
            helpBuilder.setEventId(helpRecordData.getEventId());
            helpBuilder.setRegionId(helpRecordData.getRegionId());
            DouLuoDaLuEventInfo eventInfo = douLouDaLuActivity.getEventInfo(helpRecordData.getEventId());
            if(eventInfo != null && eventInfo.getEventType() == eDouLuoDaLuEventType.PlayerEvent.getIntValue()) {
                DouLuoDaLuUserData targetUser = douLouDaLuActivity.getAllUserMap().get(helpRecordData.getTargetId());
                if(targetUser != null){
                    helpBuilder.setTargetInfo(PlayerBasePb.parsePlayerBaseTempMsg(targetUser.getUserBaseInfo()));
                    helpBuilder.setTargetTotalBlood(targetUser.getTotalBlood());
                    helpBuilder.setTargetBlood(targetUser.getBlood());
                    helpBuilder.setUserId(targetUser.getUserId());
                }
            }else {
                helpBuilder.setMonsterId((int)helpRecordData.getTargetId());
                helpBuilder.setTargetTotalBlood(helpRecordData.getTargetTotalBlood());
                helpBuilder.setTargetBlood(helpRecordData.getTargetBlood());
            }
            builder.setCurrentHelp(helpBuilder);
        }
        builder.setEvent(eventBuilder);
        return builder;
    }

    /**
     * 创建队伍
     */
    public static DouLuoDaLuProto.DouLuoDaLuCreateTeamRespMsg.Builder createTeam(int activityId, long playerId, String name, boolean hasEnoughItems) {
        DouLuoDaLuProto.DouLuoDaLuCreateTeamRespMsg.Builder builder = DouLuoDaLuProto.DouLuoDaLuCreateTeamRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId);
        if(context.getRet() !=0){
            builder.setRet(context.getRet());
            return builder;
        }
        synchronized (context.getActivity()) {
            if (context.userData.getTeamId() != 0) {
                builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_EXISTING_TEAM);
                return builder;
            }
            if (context.activity.checkTeamNameSame(name)) {
                builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_KU_TEAM_NAME_SAME);
                return builder;
            }
            long now = System.currentTimeMillis() / 1000;
            if (now <= context.userData.getLastLeaveTime() + context.activity.config.TEAM_JOIN_CD) {
                builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_STILL_DURING_CD);
                return builder;
            }
            if (context.userData.getLastCreateTime() > 0) {
                if (!hasEnoughItems) {
                    builder.setRet(GameErrorCode.E_BAG_INGOTS_NO_ENOUGH);
                    return builder;
                }
            } else {
                builder.setIsFirstCreate(true);
            }
            // 撤回申请
            context.activity.cancelApply(context.userData, true);
            DouLuoDaLuTeamData team = context.activity.createTeam(name, context.userData);
            context.getUserData().setTeamId(team.getTeamId());
            builder.setTeamInfo(buildTeamEntity(context.activity, team, false));
            builder.setRet(0);
        }
        return builder;
    }

    /**
     * 申请加入队伍
     */
    public static DouLuoDaLuProto.DouLuoDaLuJoinTeamRespMsg.Builder applyJoinTeam(int activityId, int teamId, long playerId) {
        DouLuoDaLuProto.DouLuoDaLuJoinTeamRespMsg.Builder builder = DouLuoDaLuProto.DouLuoDaLuJoinTeamRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId);
        if(context.ret !=0) {
            builder.setRet(context.ret);
            return builder;
        }
        synchronized (context.getActivity()) {
            if (context.userData.getTeamId() != 0) {
                builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_EXISTING_TEAM);
                return builder;
            }
            DouLuoDaLuTeamData team = context.activity.getAllTeamMap().get(teamId);
            if (null == team) {
                builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_TEAM_NO_EXIST);
                return builder;
            }
            if (team.getMemberList().size() >= 4) {
                builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_TEAM_MEMBER_LIMIT);
                return builder;
            }
            if (team.getMemberList().containsKey(playerId)) {
                builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_ALREADY_IN_THE_TEAM);
                return builder;
            }
            long now = System.currentTimeMillis() / 1000;
            if (now <= context.userData.getLastLeaveTime() + context.activity.config.TEAM_JOIN_CD) {
                builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_STILL_DURING_CD);
                return builder;
            }
            // 玩家申请上限
            if (context.userData.getApplyJoinTeamMap().size() >= context.activity.config.TEAM_USER_APPLY_MAX_LIMIT) {
                builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_USER_APPLY_HAS_REACHED_THE_MAXIMUM);
                return builder;
            }
            // 队伍申请上限
            if (team.getApplyList().size() >= context.activity.config.TEAM_APPLY_MAX_LIMIT) {
                builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_APPLY_HAS_REACHED_THE_MAXIMUM);
                return builder;
            }

            DouLuoDaLuUserData leader = context.activity.getAllUserMap().get(team.getCaptainId());
            // 判断是否能够跨服组队
            if (context.activity.config.TEAM_JOIN_KUAFU == 0){
                int targetGroupId = CrossUnionServerGroupMgr.getGroupIdByServerId(team.getCaptainServerId());
                int applyGroupId = CrossUnionServerGroupMgr.getGroupIdByServerId(context.getUserData().getServerId());
                if(targetGroupId != applyGroupId){
                    String leaderUnionUid = getUserActivityUnionUid(leader.getActivityId(), leader.getUserId());
                    //(如果不同区服，商会一定要一致)
                    if(team.getCaptainServerId() != context.userData.getServerId() && (!Objects.equals(context.getUnionUid(), leaderUnionUid)
                            || StringUtils.isNullOrEmpty(leaderUnionUid))){
                        builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_SUPPORT_CROSS_TEAM_UP);
                        return builder;
                    }
                }
            }
            context.userData.addApplyJoinTeam(team.getTeamId(), now);
            team.addApply(context.userData.getUserId(), now);
            // 通知队长
            DouLuoDaLuProto.DouLuoDaLuApplyChangeEntity.Builder changeBuilder = buildApplyChangeEntity(0, buildTeamApplyUserEntity(context.userData, now), null);
            MessageHelper.sendPacket(leader.getServerId(), leader.getUserId(),
                    YanQuMessageUtils.buildMessage(ClientProtocol.U_DOU_LUO_DA_LU_BROADCAST_TEAM_APPLY, changeBuilder));

        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 取消申请队伍
     */
    public static DouLuoDaLuProto.DouLuoDaLuCancelTeamApplyRespMsg.Builder cancelTeamApply(int activityId, int teamId, long playerId) {
        DouLuoDaLuProto.DouLuoDaLuCancelTeamApplyRespMsg.Builder builder = DouLuoDaLuProto.DouLuoDaLuCancelTeamApplyRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData(teamId);
        if(context.ret != 0){
            builder.setRet(context.ret);
            return builder;
        }
        synchronized (context.getActivity()) {
            context.activity.cancelApply(context.userData, context.teamData, true);
        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 退出队伍/解散队伍
     */
    public static DouLuoDaLuProto.DouLuoDaLuQuitTeamRespMsg.Builder quitTeam(int activityId, long playerId) {
        DouLuoDaLuProto.DouLuoDaLuQuitTeamRespMsg.Builder builder = DouLuoDaLuProto.DouLuoDaLuQuitTeamRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData();
        if(context.ret != 0){
            builder.setRet(context.ret);
            return builder;
        }
        int teamId = context.getTeamData().getTeamId();
        synchronized (context.getActivity()) {
            if (context.teamData.getCaptainId() == playerId) {
                // 解散队伍
                StringBuilder memberSB = new StringBuilder();
                List<Long> memberList = new ArrayList<>();
                for (Map.Entry<Long, Long> entry : context.teamData.getMemberList().entrySet()) {
                    memberList.add(entry.getKey());
                }
                for (long memberId : memberList) {
                    DouLuoDaLuUserData member = context.activity.getAllUserMap().get(memberId);
                    if (member == null) {
                        continue;
                    }
                    if (memberSB.length() > 0) {
                        memberSB.append("|");
                    }
                    memberSB.append(member.getUserId());
                    context.activity.cancelApply(member, context.teamData, false);
                    context.activity.memberQuitTeam(context.teamData, member, 2);

                    if (memberId != playerId) {
                        //日志
                        CrossAutoLogMgr.add(new LogDouLuoDaLuTeam(activityId, memberId, teamId, 0, 2));
                    }
                }
                context.activity.getTeamChatMap().remove(context.teamData.getTeamId());
                context.activity.getAllTeamMap().remove(context.teamData.getTeamId());
                context.activity.addDeleteTeam(context.teamData);
                context.teamData.setDelete(true);
                context.activity.getServerTeamMap().get(context.userData.getServerId()).remove(context.teamData);

                //日志
                CrossAutoLogMgr.add(new LogDouLuoDaLuTeam(activityId, context.getUserId(), teamId, 1, 2));

            } else {
                // 主动离开队伍
                context.activity.memberQuitTeam(context.teamData, context.userData, 3);

                context.getActivity().updateTeamTotalEarn(context.getTeamData());
                //日志
                CrossAutoLogMgr.add(new LogDouLuoDaLuTeam(activityId, playerId, teamId, 0, 4));
            }
        }

        builder.setRet(0);
        return builder;
    }

    /**
     * 入队审核
     * @param activityId
     * @param status 0表示同意 1表示拒绝 2 踢出队伍
     * @param targetUserList 目标玩家
     * @param playerId 操作玩家
     * @return
     */
    public static DouLuoDaLuProto.DouLuoDaLuTeamMemberManageRespMsg.Builder teamMemberManage(int activityId, int status, List<Long> targetUserList, long playerId) {
        DouLuoDaLuProto.DouLuoDaLuTeamMemberManageRespMsg.Builder builder = DouLuoDaLuProto.DouLuoDaLuTeamMemberManageRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData();
        if(context.ret != 0){
            builder.setRet(context.ret);
            return builder;
        }
        if(context.teamData.getCaptainId() != playerId){
            // 没有权限
            builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_MANAGE_AUTHORITY);
            return builder;
        }
        synchronized (context.getActivity()) {
            if (status == 0) {
                long targetUserId = targetUserList.get(0);
                if (context.teamData.getCaptainId() == targetUserId) {
                    // 不能对自己操作
                    builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_CAN_NOT_OPERATE_ON_ONESELF);
                    return builder;
                }
                DouLuoDaLuUserData targetUser = context.activity.getAllUserMap().get(targetUserId);
                // 同意
                if (context.teamData.getMemberList().size() >= 4) {
                    builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_TEAM_MEMBER_LIMIT);
                    return builder;
                }
                if (context.teamData.getMemberList().containsKey(targetUserId)) {
                    builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_ALREADY_IN_THE_TEAM);
                    return builder;
                }
                if (!context.teamData.getApplyList().containsKey(targetUserId)) {
                    builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_PLAYER_NOT_ON_APPLY_LIST);
                    return builder;
                }
                if (targetUser == null) {
                    builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_ACTIVITY_USER_NO_INIT);
                    return builder;
                }
                if (targetUser.getTeamId() != 0) {
                    builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_EXISTING_TEAM);
                    return builder;
                }
                context.activity.addMember(context.teamData, targetUser);
                // 取消该联盟申请
                context.activity.cancelApply(targetUser, context.teamData, false);
                // 取消其他联盟申请
                context.activity.cancelApply(targetUser, true);
                // 入队广播
                MessageHelper.sendPacket(targetUser.getServerId(), targetUser.getUserId(),
                        YanQuMessageUtils.buildMessage(ClientProtocol.U_DOU_LUO_DA_LU_BROADCAST_SUCCESS_JOIN_TEAM_INFO,
                                buildTeamEntity(context.activity, context.teamData, false)));

                context.getActivity().updateTeamTotalEarn(context.getTeamData());
                //日志
                CrossAutoLogMgr.add(new LogDouLuoDaLuTeam(activityId, targetUserId, context.getTeamData().getTeamId(), 0, 1));

            } else if (status == 1) {
                for (long targetUserId : targetUserList) {
                    if (context.teamData.getCaptainId() == targetUserId) {
                        continue;
                    }
                    DouLuoDaLuUserData targetUser = context.activity.getAllUserMap().get(targetUserId);
                    // 拒绝
                    if (targetUser != null) {
                        context.activity.cancelApply(targetUser, context.teamData, false);
                    }
                }
            } else {
                long targetUserId = targetUserList.get(0);
                if (context.teamData.getCaptainId() == targetUserId) {
                    // 不能对自己操作
                    builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_CAN_NOT_OPERATE_ON_ONESELF);
                    return builder;
                }
                DouLuoDaLuUserData targetUser = context.activity.getAllUserMap().get(targetUserId);
                if (targetUser == null) {
                    builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_TARGET_NO_EXIST);
                    return builder;
                }
                // 踢出队伍
                if (targetUser.getTeamId() != context.teamData.getTeamId()) {
                    builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_PLAYER_NOT_IN_TEAM);
                    return builder;
                }
                context.activity.memberQuitTeam(context.teamData, targetUser, 1);

                context.getActivity().updateTeamTotalEarn(context.getTeamData());
                //日志
                CrossAutoLogMgr.add(new LogDouLuoDaLuTeam(activityId, targetUserId, context.getTeamData().getTeamId(), 0, 3));
            }
        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 发送队伍聊天
     */
    public static void teamChat(int activityId, WorldMessageProto.WorldMessageTempMsg msg){
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, msg.getUserId()).loadTeamData();
        if(context.ret != 0){
            return;
        }
        context.activity.addTeamChat(context.teamData, context.userData,0, msg.getContentType(), msg.getContent(),System.currentTimeMillis()/1000);
    }

    //玩法-----------------------------------
    /**
     * 探索
     */
    public static DouLuoDaLuProto.DouLuoDaLuExploreRespMsg.Builder explore(int activityId, long playerId, long stoneNum, long lowBoxConsumeCount, long highBoxConsumeCount) {
        DouLuoDaLuProto.DouLuoDaLuExploreRespMsg.Builder respMsg = DouLuoDaLuProto.DouLuoDaLuExploreRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData();
        if(context.getRet() != 0){
            respMsg.setRet(context.getRet());
            return respMsg;
        }
        DouLuoDaLuEventResult eventResult;
        DouLuoDaLuEventInfo eventInfo;
        List<Integer> buffList = new ArrayList<>();
        int regionId;
        //探索，锁加在玩家身上，不然被打死掉区域，随机的事件就有问题
        synchronized (context.getActivity()) {
            if (hasEvent(context.getUserData().getEvent())) {
                respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_USER_EXIST_EVENT);
                return respMsg;
            }
            eventInfo = context.getActivity().randomRegionEventNew(context.getUserData(), new ArrayList<>(), stoneNum, lowBoxConsumeCount, highBoxConsumeCount);
            if (eventInfo == null) {
                respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_CONFIG_NOT_EXIST);
                return respMsg;
            }
            DouLuoDaLuRegionInfo regionInfo = context.getActivity().getConfig().getRegionInfo(context.getUserData().getRegionId());
            if(regionInfo == null){
                respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_CONFIG_NOT_EXIST);
                return respMsg;
            }

            buffList.add(eDouLuoDaLuBuffType.ENERGY_BUFF.getId());
            buffList = mergeXianCaoAndUse(context.getUserData(), buffList);

            if(!buffList.contains(eDouLuoDaLuBuffType.ENERGY_BUFF.getId())) {
                //体力是否充足
                context.getActivity().refreshUserEnergy(context.userData, true);
                if (regionInfo.getEnergy() > context.getUserData().getEnergy()) {
                    respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_ENERGY_NO_ENOUGH);
                    return respMsg;
                }
            }

            IDouLuoDaLuUserEventAction eventAction = DouLuoDaLuBaseEventAction.createAction(context, eventInfo);
            eventResult = eventAction.init();

            //如果真人事件初始失败，没有真人可随机，则重新随机事件，排除真人事件
            if(eventResult.getRet() == -1){
                // 替换事件
                eventInfo = context.getActivity().randomRegionEventNew(context.getUserData(), context.getActivity().getConfig().getEventPvpExchangeId(), stoneNum, lowBoxConsumeCount, highBoxConsumeCount);
                if (eventInfo == null) {
                    respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_CONFIG_NOT_EXIST);
                    return respMsg;
                }
                eventAction = DouLuoDaLuBaseEventAction.createAction(context, eventInfo);
                eventResult = eventAction.init();
            }
            respMsg.setEnergy(context.getUserData().getEnergy());
            if(!buffList.contains(eDouLuoDaLuBuffType.ENERGY_BUFF.getId())) {
                context.getUserData().setEnergy(context.getUserData().getEnergy() - regionInfo.getEnergy());
                context.getUserData().setUseEnergy(context.getUserData().getUseEnergy() + regionInfo.getEnergy());
            }
            regionId = context.getUserData().getRegionId();

            exploreEventCount(context.getUserData(), eventInfo);
        }

        //返回结果
        if(eventResult.getRet() == 0){
            DouLuoDaLuUserEvent userEvent = eventResult.getUserEvent();
            respMsg.setEventId(userEvent.getEventId());
            respMsg.setTeamId(context.getUserData().getTeamId());
            respMsg.setRegionId(regionId);
            respMsg.setEnemyId(0);
            //玩家事件
            if(userEvent.getEnemyUserId() > 0){
                DouLuoDaLuUserData enemyUserData = context.getActivity().getAllUserMap().get(userEvent.getEnemyUserId());
                if(enemyUserData != null){
                    respMsg.setBlood(enemyUserData.getTotalBlood());
                    respMsg.setRemainBlood(enemyUserData.getBlood());
                    respMsg.setTargetInfo(PlayerBasePb.parsePlayerBaseTempMsg(enemyUserData.getUserBaseInfo()));
                    respMsg.setEnemyId(enemyUserData.getUserId());
                }
            }else if(userEvent.getMonsterId() > 0){
                //魂兽事件
                respMsg.setMonsterId(userEvent.getMonsterId());
                respMsg.setBlood(userEvent.getTotalBlood());
                respMsg.setRemainBlood(userEvent.getBlood());
            }
        }
        respMsg.addAllBuff(buffList);
        respMsg.setRet(eventResult.getRet());
        return respMsg;
    }
    /**
     * 事件处理
     * @param playerId
     * @param action
     * @param msg
     * @return
     */
    public static DouLuoDaLuProto.DouLuoDaLuEventHandleCrossRespMsg.Builder handleEvent(int activityId, long playerId, int action, String consume, byte[] msg, int clientEventId) {
        DouLuoDaLuProto.DouLuoDaLuEventHandleCrossRespMsg.Builder respMsg = DouLuoDaLuProto.DouLuoDaLuEventHandleCrossRespMsg.newBuilder();
        respMsg.setAction(action);
        if(!StringUtils.isNullOrEmpty(consume)){
            respMsg.setConsume(consume);
        }
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData();
        if(context.getRet() != 0){
            respMsg.setRet(context.ret);
            return respMsg;
        }
        DouLuoEventHandleResult eventHandleResult;

        DouLuoDaLuUserEvent userEvent = context.getUserData().getEvent();
        if (!hasEvent(userEvent)) {
            if(context.getActivity().getConfig().getPlayerEventId().contains(clientEventId)){
                respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_PLAYER_NOT_IN_REGION);
            }else {
                respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_USER_NOT_EVENT);
            }
            return respMsg;
        }

        DouLuoDaLuEventInfo eventInfo = context.getActivity().getEventInfo(userEvent.getEventId());
        IDouLuoDaLuUserEventAction eventAction = DouLuoDaLuBaseEventAction.createAction(context, eventInfo);
        eventHandleResult = eventAction.handle(action, msg);
        if(eventHandleResult.getRet() != 0){
            respMsg.setRet(eventHandleResult.getRet());
            return respMsg;
        }
        if(!StringUtils.isNullOrEmpty(eventHandleResult.getHunHuan())) {
            respMsg.setHunHuan(eventHandleResult.getHunHuan());
        }
        respMsg.setReward(eventHandleResult.getRewards());
        respMsg.setEventId(eventHandleResult.getEventId());
        respMsg.setBlood(eventHandleResult.getBlood());
        respMsg.setDamage(eventHandleResult.getDamage());
        respMsg.setScore(eventHandleResult.getScore());
        respMsg.setAllScore(eventHandleResult.getAllScore());
        respMsg.addAllBuff(eventHandleResult.getBuffIdList());
        respMsg.setTeamId(context.getUserData().getTeamId());
        DouLuoDaLuUserEvent resultUserEvent = eventHandleResult.getUserEvent();
        respMsg.setRegionId(resultUserEvent.getRegionId());
        respMsg.setEventStatus(resultUserEvent.getStatus());
        respMsg.setEventTime(resultUserEvent.getAddTime());
        if(resultUserEvent.getEventType() == eDouLuoDaLuEventType.PlayerEvent.getIntValue()) {
            respMsg.setTargetId(resultUserEvent.getEnemyUserId());
        }
        if(resultUserEvent.getEventType() == eDouLuoDaLuEventType.MonsterEvent.getIntValue()) {
            respMsg.setTargetId(resultUserEvent.getMonsterId());
        }
        respMsg.setRet(0);
        return respMsg;
    }

    /**
     * 协助/领取协助奖励
     */
    public static DouLuoDaLuProto.DouLuoDaLuHelpActionCrossRespMsg.Builder helpAction(int activityId, long playerId, long recordId, int type) {
        DouLuoDaLuProto.DouLuoDaLuHelpActionCrossRespMsg.Builder builder = DouLuoDaLuProto.DouLuoDaLuHelpActionCrossRespMsg.newBuilder();
        DouLuoDaLuProto.DouLuoDaLuHelpActionRespMsg.Builder clientBuilder = DouLuoDaLuProto.DouLuoDaLuHelpActionRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData();
        if(context.getRet() != 0){
            clientBuilder.setRet(context.getRet());
            builder.setRespClient(clientBuilder);
            return builder;
        }
        if(type == 0){
            DouLuoDaLuHelpRecordData recordData = null;
            DouLuoDaLuEventInfo eventInfo;
            synchronized (context.getActivity()) {
                //领奖
                List<DouLuoDaLuHelpRecordData> myList = context.getActivity().getHelpRecordDataMap().get(playerId);
                for (DouLuoDaLuHelpRecordData data : myList) {
                    if (data.getId() == recordId) {
                        recordData = data;
                    }
                }
                if (recordData == null) {
                    //协助记录不存在
                    clientBuilder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HELP_RECORD_NO_FOUND);
                    builder.setRespClient(clientBuilder);
                    return builder;
                }
                if (recordData.getKilledUserId() <= 0) {
                    // 未被击杀
                    clientBuilder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_REWARD_CONDITION);
                    builder.setRespClient(clientBuilder);
                    return builder;
                }
                if (recordData.isReceived()) {
                    clientBuilder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_CANNOT_BE_REPEATED_REWARD);
                    builder.setRespClient(clientBuilder);
                    return builder;
                }
                if (StringUtils.isNullOrEmpty(recordData.getReward()) && StringUtils.isNullOrEmpty(recordData.getHunHuan())) {
                    //奖励还在计算
                    clientBuilder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_REWARD_CONDITION);
                    builder.setRespClient(clientBuilder);
                    return builder;
                }
                eventInfo = context.getActivity().getConfig().getEventInfo(recordData.getEventId());
                if (eventInfo == null) {
                    clientBuilder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_CONFIG_NOT_EXIST);
                    builder.setRespClient(clientBuilder);
                    return builder;
                }
                //只有魂环、普通道具奖励
                recordData.setIsReceived(true);
                //拿出魂环奖励
                CrossDouLuoDaLuMgr.addHunHuanReward(PropertyHelper.parseStringToProperty(recordData.getHunHuan()), context);
            }
            clientBuilder.setReward(recordData.getReward());
            clientBuilder.setHunHuan(recordData.getHunHuan());

            //魂环日志
            CrossAutoLogMgr.add(new LogDouLuoDaLuHunHuan(activityId, context.getUserId(), 1, recordData.getRegionId(), recordData.getHunHuan(),
                    eventInfo.getEventType() == eDouLuoDaLuEventType.PlayerEvent.getIntValue() ? 2 : 1, recordData.getTargetId()));

        }else {
            DouLuoEventHandleResult handleResult = new DouLuoEventHandleResult();
            DouLuoDaLuHelpRecordData recordData;
            DouLuoDaLuEventInfo eventInfo;
            synchronized (context.getActivity()){
                Map<Long, DouLuoDaLuHelpRecordData> map = context.getActivity().getHelpRecordDataMap(context.getTeamData());
                recordData = map.get(recordId);
                //协助记录不存在
                if (recordData == null) {
                    clientBuilder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HELP_RECORD_NO_FOUND);
                    builder.setRespClient(clientBuilder);
                    return builder;
                }
                if (getCanHelpTimes(context.getUserData(), context.getActivity().config) <= 0) {
                    clientBuilder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_HELP_TIMES);
                    builder.setRespClient(clientBuilder);
                    return builder;
                }
                //队友信息
                DouLuoDaLuUserData friendUser = context.getActivity().getAllUserMap().get(recordData.getUserId());
                eventInfo = context.getActivity().getConfig().getEventInfo(recordData.getEventId());
                DouLuoDaLuRegionInfo regionInfo = context.getActivity().getConfig().getRegionInfo(recordData.getRegionId());

                //抢的魂环
                Property hunHuanProperty = new Property();
                //道具奖励
                Property goodsProperty = new Property();
                long now;
                if (eventInfo.getEventType() == eDouLuoDaLuEventType.PlayerEvent.getIntValue()) {
                    //玩家是否损失魂环
                    boolean enemyLost = false;
                    //对手
                    DouLuoDaLuUserData enemyUser = context.getActivity().getAllUserMap().get(recordData.getTargetId());
                    //标志对手的玩家
                    Set<DouLuoDaLuUserData> markEnemySet;
                    //对手旧区域
                    int oldRegionId;
                    DouLuoDaLuRegionInfo preRegionInfo;

                    now = System.currentTimeMillis();
                    handleResult.setTime(DateHelper.getCurrentSecond());
                    oldRegionId = enemyUser.getRegionId();
                    preRegionInfo = context.getActivity().getConfig().getPreRegionInfo(oldRegionId);
                    //双重判定
                    map = context.getActivity().getHelpRecordDataMap(context.getTeamData());
                    if (map.get(recordId) == null || recordData != map.get(recordId)) {
                        //协助记录不存在
                        clientBuilder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HELP_RECORD_NO_FOUND);
                        builder.setRespClient(clientBuilder);
                        return builder;
                    }
                    if (enemyUser.getRegionId() != recordData.getRegionId()) {
                        clientBuilder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_PLAYER_NOT_IN_REGION);
                        builder.setRespClient(clientBuilder);
                        return builder;
                    }
                    if (!canHelp(builder, clientBuilder, context, recordData)) return builder;

                    context.getActivity().attackDamage(context.getUserData().getHunLi(), enemyUser.getBlood(), handleResult);
                    //更新血量与CD
                    enemyUser.setBlood(handleResult.getBlood());
                    recordData.setTargetBlood(handleResult.getBlood());
                    updateAttackInfo(context.getUserData(), recordData, handleResult.getDamage(), handleResult.getTime());

                    DouLuoDaLuUserEvent userEvent = context.getUserData().getEvent();
                    if (userEvent.getEnemyUserId() == enemyUser.getUserId()) {
                        if (handleResult.isKill()) {
                            context.getUserData().setEvent(new DouLuoDaLuUserEvent());
                        } else {
                            userEvent.setAttackTime(handleResult.getTime());
                            userEvent.setBlood(handleResult.getBlood());
                            if (userEvent.getStatus() == 0) {
                                userEvent.setStatus(1);
                            }
                        }
                        notifyUserEventInfo(context.getUserData(), handleResult);
                    }

                    //更新我的协助记录
                    DouLuoDaLuHelpRecordData helpRecordData = context.getUserData().getCurrentHelpRecordData();
                    if (helpRecordData != null && helpRecordData.getTargetId() == enemyUser.getUserId()) {
                        helpRecordData.setTargetBlood(handleResult.getBlood());
                        CrossDouLuoDaLuMgr.updateAttackInfo(context.getUserData(), helpRecordData, handleResult.getDamage(), handleResult.getTime());
                        if (handleResult.isKill()) {
                            updateHelpDataKillInfo(helpRecordData, context.getUserId(), now, context.userData);
                            context.getUserData().setCurrentHelpRecordData(null);
                        }
                    }

                    if (handleResult.isKill()) {
                        updateHelpDataKillInfo(recordData, context.getUserId(), now, friendUser);

                        enemyLost = calBattleReward(hunHuanProperty, goodsProperty, context, regionInfo, eventInfo, enemyUser);

                        preRegionInfo = dropRegionInfo(context.getActivity(), enemyUser);

                        markEnemySet = enemyUser.getCanAttackUserSet();
                        enemyUser.setCanAttackUserSet(new ConcurrentHashSet<>());

                        //通知对手被击败了
                        pushEnemyTip(context, handleResult, enemyUser, hunHuanProperty, enemyLost, 2);

                        //更新对手被击败次数
                        enemyUser.getEnemyInfoMap().put(context.getUserId(), enemyUser.getEnemyInfoMap().getOrDefault(context.getUserId(), 0) + 1);

                        //击杀日志
                        CrossAutoLogMgr.add(new LogDouLuoDaLuKill(context.getActivityId(), context.getUserId(), recordData.getRegionId(),
                                2, enemyUser.getUserId(), handleResult.getDamage(), recordData.getUserId(), recordData.getRecordTime(), recordData.getEventTIme(), handleResult.getTime()));

                        //魂环日志
                        if (recordData.getUserId() == context.getUserId()) {
                            CrossAutoLogMgr.add(new LogDouLuoDaLuHunHuan(activityId, context.getUserId(), 1, recordData.getRegionId(), PropertyHelper.parsePropertyToString(hunHuanProperty),
                                    LogDouLuoDaLuHunHuan.getReason(2, enemyLost), enemyUser.getUserId()));
                        }

                        CrossAutoLogMgr.add(new LogDouLuoDaLuHunHuan(activityId, enemyUser.getUserId(), 0, recordData.getRegionId(), PropertyHelper.parsePropertyToString(hunHuanProperty),
                                LogDouLuoDaLuHunHuan.getReason(3, enemyLost), context.getUserId()));


                    } else {
                        markEnemySet = enemyUser.getCanAttackUserSet();
                    }

                    if (handleResult.isKill()) {
                        context.getActivity().removeAreaUser(oldRegionId, enemyUser.getUserId());
                        context.getActivity().addAreaUser(preRegionInfo.getRegionId(), enemyUser);
                    }

                    //对手的防守日志
                    CrossDouLuoDaLuMgr.notifyUserBeFight(context.getUserData(), enemyUser, handleResult.getDamage(), handleResult.getBlood(), 2,
                            enemyLost ? handleResult.getHunHuan() : null);

                    //森林事件日志
                    if (eventInfo.isShowLog() && CrossDouLuoDaLuMgr.containHunHuan(hunHuanProperty, 10000)) {
                        DouLuoDaLuEventNoticeData noticeData = context.getActivity().addEventNotice(context.getUserData(), eventInfo, 0,
                                friendUser == context.getUserData() ? PropertyHelper.parsePropertyToString(hunHuanProperty) : "", "", null, enemyUser, 2, friendUser);
                        context.getActivity().syncDouLuoDaLuEventNotice(noticeData);
                    }

                    //攻击事件广播
                    CrossDouLuoDaLuMgr.handleAttackPlayerEventBroadcast(handleResult, context, markEnemySet, enemyUser, handleResult.getTime());

                } else {
                    // 魂兽事件协助
                    now = System.currentTimeMillis();
                    handleResult.setTime(DateHelper.getCurrentSecond());
                    //双重判定
                    map = context.getActivity().getHelpRecordDataMap(context.getTeamData());
                    if (map.get(recordId) == null || recordData != map.get(recordId)) {
                        //协助记录不存在
                        clientBuilder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HELP_RECORD_NO_FOUND);
                        builder.setRespClient(clientBuilder);
                        return builder;
                    }
                    if (!canHelp(builder, clientBuilder, context, recordData)) return builder;

                    context.getActivity().attackDamage(context.getUserData().getHunLi(), recordData.getTargetBlood(), handleResult);
                    //更新血量与CD
                    recordData.setTargetBlood(handleResult.getBlood());
                    updateAttackInfo(context.getUserData(), recordData, handleResult.getDamage(), handleResult.getTime());

                    //是否在事件中
                    DouLuoDaLuUserEvent userEvent = context.getUserData().getEvent();
                    if (friendUser == context.getUserData() && userEvent.getAddTime() == recordData.getEventTIme()) {
                        if (handleResult.isKill()) {
                            context.getUserData().setEvent(new DouLuoDaLuUserEvent());
                        } else {
                            userEvent.setBlood(handleResult.getBlood());
                            userEvent.setAttackTime(handleResult.getTime());
                        }
                    }

                    if (handleResult.isKill()) {
                        updateHelpDataKillInfo(recordData, context.getUserId(), now, friendUser);
                        calBattleReward(hunHuanProperty, goodsProperty, context, regionInfo, eventInfo, null);

                        if (friendUser.getCurrentHelpRecordData() == recordData) {
                            friendUser.setCurrentHelpRecordData(null);
                        }
                        if (friendUser.getEvent().getStatus() == 2 && friendUser.getEvent().getAddTime() == recordData.getEventTIme()) {
                            friendUser.setEvent(new DouLuoDaLuUserEvent());
                        }

                        //击杀日志
                        CrossAutoLogMgr.add(new LogDouLuoDaLuKill(context.getActivityId(), context.getUserId(), recordData.getRegionId(),
                                1, recordData.getTargetId(), handleResult.getDamage(), recordData.getUserId(), recordData.getRecordTime(), recordData.getEventTIme(), handleResult.getTime()));

                        //魂环日志
                        if (recordData.getUserId() == context.getUserId()) {
                            CrossAutoLogMgr.add(new LogDouLuoDaLuHunHuan(activityId, context.getUserId(), 1, recordData.getRegionId(), PropertyHelper.parsePropertyToString(hunHuanProperty), 1, recordData.getTargetId()));
                        }

                    } else {
                        if (friendUser.getCurrentHelpRecordData() == recordData) {
                            if (friendUser.getEvent().getStatus() == 2 && friendUser.getEvent().getAddTime() == recordData.getEventTIme()) {
                                friendUser.getEvent().setBlood(handleResult.getBlood());
                            }
                        }
                    }

                    //通知被协助者,血量变化
                    if (recordData.getUserId() != context.getUserId()) {
                        notifyUserEventInfo(friendUser, handleResult);
                    }

                    if (handleResult.isKill()) {
                        //森林日志
                        if (eventInfo.isShowLog()) {
                            context.getActivity().addEventNotice(context.getUserData(), eventInfo, (int) recordData.getTargetId(),
                                    friendUser == context.getUserData() ? PropertyHelper.parsePropertyToString(hunHuanProperty) : "", "", null, null, 2, friendUser);
                        }
                    }
                }

                //结算
                long addScore = calAddScore(handleResult.getDamage(), recordData.getTargetTotalBlood(), eventInfo, regionInfo);
                //积分冲榜
                context.getUserData().setScore(addScore + context.getUserData().getScore());
                changeRank(context.getUserData());

                handleResult.setScore(addScore);
                handleResult.setAllScore(context.getUserData().getScore());
                if (handleResult.isKill()) {
                    //奖励
                    recordData.setHunHuan(PropertyHelper.parsePropertyToString(hunHuanProperty));
                    recordData.setReward(PropertyHelper.parsePropertyToString(goodsProperty));
                    if (recordData.getUserId() == context.getUserId()) {

                        addHunHuanReward(hunHuanProperty, context);
                        handleResult.setHunHuan(PropertyHelper.parsePropertyToString(hunHuanProperty));
                        if (context.getUserData().getRegionId() == recordData.getRegionId()) {
                            completeEventCount(context.getUserData(), eventInfo);
                        }

                        recordData.setIsReceived(true);
                        handleResult.setRewards(recordData.getReward());
                        handleResult.setHunHuan(recordData.getHunHuan());
                    } else {
                        if (friendUser.getRegionId() == recordData.getRegionId()) {
                            completeEventCount(friendUser, eventInfo);
                        }
                    }
                    context.getActivity().checkUserRedHot(friendUser, context.getTeamData());

                    //context.getActivity().broadcastHelpRecordAttackInfo(context.getTeamData());
                } else {
                    List userList = new ArrayList();
                    userList.add(context.getUserData());
                    //context.getActivity().broadcastHelpRecordAttackInfo(userList, context.getTeamData());
                }
                context.userData.setHelpTimes(context.getUserData().getHelpTimes() + 1);
            }
            clientBuilder.setIsKill(handleResult.isKill());
            clientBuilder.setRemainBlood(handleResult.getBlood());
            clientBuilder.setHunHuan(handleResult.getHunHuan());
            clientBuilder.setDamage(handleResult.getDamage());
            clientBuilder.setReward(handleResult.getRewards());
            clientBuilder.setScore(handleResult.getScore());
            clientBuilder.setAllScore(handleResult.getAllScore());
            if(handleResult.isKill()){
                DouLuoDaLuProto.DouLuoDaLuHelpActionLogEntity.Builder logBuilder = DouLuoDaLuProto.DouLuoDaLuHelpActionLogEntity.newBuilder();
                logBuilder.setRegionId(recordData.getRegionId());
                logBuilder.setTeamId(context.getTeamData().getTeamId());
                logBuilder.setStatus(2);
                logBuilder.setAfterAttackBlood(handleResult.getBlood());
                logBuilder.setBeforeAttackBlood(handleResult.getDamage() + handleResult.getBlood());
                logBuilder.setTargetId(recordData.getTargetId());
                logBuilder.setEventId(recordData.getEventId());
                logBuilder.setEventType(eventInfo.getEventType());
                logBuilder.setEventTime(recordData.getEventTIme());
                builder.setLog(logBuilder);
            }
            //协助记录
            for(Map.Entry<Long, DouLuoDaLuAttackInfo> entry : recordData.getHelpAttackMap().entrySet()){
                if(recordData.getUserId() != entry.getKey()){
                    clientBuilder.addHelpAttackList(buildHelpAttackEntity(context, entry.getKey(), entry.getValue()));
                }
            }

            //积分获得日志
            if(handleResult.getScore() > 0){
                CrossAutoLogMgr.add(new LogDouLuoDaLuScoreChange(context.getActivityId(), context.getUserId(), context.getActivity().getConfig().SCORE_ITEM_ID_FOREST,
                        1, handleResult.getScore(), handleResult.getAllScore()));
            }
        }

        clientBuilder.setRet(0);
        builder.setRespClient(clientBuilder);
        return builder;
    }

    private static void notifyUserEventInfo(DouLuoDaLuUserData friendUser, DouLuoEventHandleResult handleResult) {
        DouLuoDaLuProto.BroadcastDouLuoDaLuEventInfo.Builder notify = DouLuoDaLuProto.BroadcastDouLuoDaLuEventInfo.newBuilder();
        notify.setType(handleResult.isKill() ? 2 : 1);
        notify.setRemainBlood(handleResult.getBlood());
        notify.setDamage(handleResult.getDamage());
        MessageHelper.sendPacket(friendUser.getServerId(), friendUser.getUserId(), YanQuMessageUtils.buildMessage(Protocol.U_DOU_LUO_DA_LU_BROADCAST_EVENT_INFO, notify));
    }

    public static void completeEventCount(DouLuoDaLuUserData userData, DouLuoDaLuEventInfo eventInfo) {
        //事件完成统计(事件类型，完成次数)
        Map<Integer, Integer> finishEventMap = userData.getFinishEventMap();
        int count = finishEventMap.getOrDefault(eventInfo.getEventId(), 0);
        finishEventMap.put(eventInfo.getEventId(), count + 1);
    }

    public static void exploreEventCount(DouLuoDaLuUserData userData, DouLuoDaLuEventInfo eventInfo){
        //探索次数统计（区域，次数）
        int regionId = userData.getRegionId();
        int count = userData.getRegionEventMap().getOrDefault(regionId, 0);
        userData.getRegionEventMap().put(regionId, count + 1);
        userData.setUpdateOption();
    }

    /**
     * 更新协助记录击杀信息
     */
    public static void updateHelpDataKillInfo(DouLuoDaLuHelpRecordData helpRecordData, long killUserId, long killTime, DouLuoDaLuUserData helpRecordOwner){
        if(helpRecordData.getKilledUserId() == 0){
            helpRecordData.setKillTime(killTime);
            helpRecordData.setKilledUserId(killUserId);
            if(helpRecordData.getUserId() == killUserId){
                helpRecordData.setIsReceived(true);
            }
        }
        if(helpRecordData == helpRecordOwner.getCurrentHelpRecordData()){
            helpRecordOwner.setCurrentHelpRecordData(null);
        }
    }

    public static void updateAttackInfo(DouLuoDaLuUserData userData, DouLuoDaLuHelpRecordData recordData, long damage, int now) {
        DouLuoDaLuAttackInfo attackInfo = recordData.getHelpAttackMap().get(userData.getUserId());
        if(attackInfo == null){
            recordData.getHelpAttackMap().put(userData.getUserId(), new DouLuoDaLuAttackInfo(now, damage));
        }else {
            attackInfo.setAttackTime(now);
            attackInfo.setDamage(attackInfo.getDamage() + damage);
        }
        recordData.setUpdateOption();
    }

    private static DouLuoDaLuProto.DouLuoDaLuHelpAttackEntity.Builder buildHelpAttackEntity(CrossDouLuoDaLuContext context, long userId, DouLuoDaLuAttackInfo attackInfo) {
        DouLuoDaLuProto.DouLuoDaLuHelpAttackEntity.Builder builder = DouLuoDaLuProto.DouLuoDaLuHelpAttackEntity.newBuilder();
        DouLuoDaLuUserData helpUser = context.getActivity().getAllUserMap().get(userId);
        if(helpUser != null){
            builder.setHelperName(helpUser.getUserBaseInfo().getNickName());
            builder.setHelperServerId(helpUser.getServerId());
            builder.setDamage(attackInfo.getDamage());
        }
        return builder;
    }

    /**
     * 区域传送
     */
    public static DouLuoDaLuProto.DouLuoDaLuChangeRegionCrossRespMsg.Builder changeRegion(int activityId, long playerId, String consume, int regionId, int consumeType) {
        DouLuoDaLuProto.DouLuoDaLuChangeRegionCrossRespMsg.Builder builder = DouLuoDaLuProto.DouLuoDaLuChangeRegionCrossRespMsg.newBuilder();
        builder.setConsume(consume);
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData();
        if(context.ret != 0){
            builder.setRet(context.ret);
            return builder;
        }

        DouLuoDaLuUserData userData = context.getUserData();
        int oldRegionId;
        synchronized (context.getActivity()) {
            DouLuoDaLuRegionInfo regionInfo = context.getActivity().getConfig().getNextRegionInfo(userData.getRegionId());
            if (regionInfo == null || regionId != regionInfo.getRegionId()) {
                builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_CONFIG_NOT_EXIST);
                return builder;
            }
            if(consumeType == 2){
                if(regionInfo.getUpgradeConsumeList().size() == 1){
                    builder.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
                    return builder;
                }
                String taskCondition = regionInfo.getUpgradeConsumeList().get(1);
                List<Integer> params = StringUtils.stringToIntegerList(taskCondition, "=");
                int eventId = params.get(0);
                DouLuoDaLuEventInfo eventInfo = context.getActivity().getConfig().getEventInfo(eventId);
                if(eventInfo == null){
                    builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_CONFIG_NOT_EXIST);
                    return builder;
                }
                List<DouLuoDaLuEventInfo> eventInfoList = context.getActivity().getConfig().getEventInfoList(eventInfo.getEventType());
                List<Integer> eventIdList = new ArrayList<>();
                for (DouLuoDaLuEventInfo eInfo : eventInfoList) {
                    if(eInfo.getEventId() >= eventId) {
                        eventIdList.add(eInfo.getEventId());
                    }
                }
                int value = 0;
                for (Map.Entry<Integer, Integer> entry : context.getUserData().getFinishEventMap().entrySet()) {
                   if(eventIdList.contains(entry.getKey())){
                       value += entry.getValue();
                   }
                }
                if(value < params.get(1)){
                    builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NOT_REACH_CHANGE_CONDITION);
                    return builder;
                }
            }
            oldRegionId = userData.getRegionId();
            userData.addOpenRegionId(regionId);
            resetUserDataForChangeRegion(userData, regionInfo);

            context.getActivity().checkUserRedHot(userData, context.getTeamData());

            Iterator<DouLuoDaLuUserData> iterator = userData.getCanAttackUserSet().iterator();
            while (iterator.hasNext()){
                DouLuoDaLuUserData  data = iterator.next();
                DouLuoDaLuHelpRecordData currentHelpRecordData = data.getCurrentHelpRecordData();
                if(currentHelpRecordData != null && currentHelpRecordData.getTargetId() == userData.getUserId()){
                    updateHelpDataKillInfo(currentHelpRecordData, -1, 0, data);
                }
                if(data.getEvent().getEventType() == eDouLuoDaLuEventType.PlayerEvent.getIntValue() && data.getEvent().getEnemyUserId() == userData.getUserId()){
                    data.setEvent(new DouLuoDaLuUserEvent());
                }
            }
            userData.setCanAttackUserSet(new ConcurrentHashSet<>());
            context.getActivity().removeAreaUser(oldRegionId, userData.getUserId());
            context.getActivity().addAreaUser(regionId, userData);
        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 开宝箱
     */
    public static DouLuoDaLuProto.DouLuoDaLuOpenBoxToGameServerMsg.Builder openBox(int activityId, long playerId, int boxId, int num) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, playerId);

        DouLuoDaLuProto.DouLuoDaLuOpenBoxToGameServerMsg.Builder resp = DouLuoDaLuProto.DouLuoDaLuOpenBoxToGameServerMsg.newBuilder();
        resp.setBoxId(boxId);
        resp.setNum(num);
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData();
        if (context.ret != 0) {
            resp.setRet(context.ret);
            return resp;
        }
        CrossDouLouDaLuActivity activity = CrossDouLuoDaLuMgr.getActivity(activityId, groupId);
        if(activity == null){
            resp.setRet(GameErrorCode.E_ACTIVITY_OVER_TIME);
            return resp;
        }
        DouLuoDaLuConfig config = activity.getConfig();
        //仅防止自己并发
        synchronized (context.getUserData()) {
            int boxNum = context.getUserData().getBoxMap().getOrDefault(boxId, 0);
            if (boxNum < num) {
                resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NOT_YOUR_BOX);
                return resp;
            }
            // 扣宝箱
            context.getUserData().getBoxMap().put(boxId, boxNum - num);
            context.getUserData().setOp(DataStatus.Update);
        }
        resp.setRegionId(context.getUserData().getRegionId());
        resp.setTeamId(context.getUserData().getTeamId());
        resp.setRet(0);
        String eventReward = "";
        String boxIdStr = String.valueOf(boxId);
        for (DouLuoDaLuEventInfo eventInfo : config.getEventInfoList()) {
            if(eventInfo.getTargetId().equals(boxIdStr)){
                eventReward = eventInfo.getRewards();
                break;
            }
        }
        Property reward = new Property();
        Random random = new Random();
        for (int i = 0; i < num; i++) {
            reward.addProperty(RandomWeightConfigHelper.getProperty(eventReward, random));
        }
        resp.setReward(PropertyHelper.parsePropertyToString(reward));
        return resp;
    }

    /**
     * 使用道具恢复体力
     */
    public static DouLuoDaLuProto.DouLuoDaLuRecoverEnergyRespMsg.Builder recoverEnergy(int activityId, long playerId, int num) {
        DouLuoDaLuProto.DouLuoDaLuRecoverEnergyRespMsg.Builder respMsg = DouLuoDaLuProto.DouLuoDaLuRecoverEnergyRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData();
        respMsg.setNum(num);
        if(context.getRet() != 0){
            respMsg.setRet(context.getRet());
            return respMsg;
        }
        //仅防止自己并发
        synchronized (context.getUserData()) {
            context.getActivity().refreshUserEnergy(context.userData, false);
            GoodsInfo goodsInfo = TempCommonMgr.getGoodsInfo(context.getActivity().config.ENERGY_ITEM_ID);
            if (goodsInfo == null) {
                respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_CONFIG_NOT_EXIST);
                return respMsg;
            }
            context.getUserData().setEnergy(context.getUserData().getEnergy() + (num * goodsInfo.getParamList().get(0).intValue()));
        }
        respMsg.setEnergy(context.getUserData().getEnergy());
        respMsg.setEnergyLastTime(context.getUserData().getEnergyLastTime());
        respMsg.setRet(0);
        return respMsg;
    }

    /**
     * 查看区域
     */
    public static DouLuoDaLuProto.DouLuoDaLuGetRegionUserInfoRespMsg.Builder viewRegionInfo(int activityId, long playerId, int regionId) {
        DouLuoDaLuProto.DouLuoDaLuGetRegionUserInfoRespMsg.Builder resp = DouLuoDaLuProto.DouLuoDaLuGetRegionUserInfoRespMsg.newBuilder();
        resp.setRegionId(regionId);
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData();
        if(context.ret != 0){
            resp.setRet(context.ret);
            return resp;
        }
        DouLuoDaLuRegionInfo regionInfo = context.getActivity().getConfig().getRegionInfo(regionId);
        if(regionInfo == null){
            resp.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
            return resp;
        }
        Map<Long, DouLuoDaLuUserData> userDataMap = context.getActivity().getAreaUserMap().get(regionId);
        if(userDataMap != null){
            for (Map.Entry<Long, DouLuoDaLuUserData> dataEntry : userDataMap.entrySet()) {
                DouLuoDaLuUserData userData = dataEntry.getValue();
                DouLuoDaLuProto.RegionUserInfoEntity.Builder entity = DouLuoDaLuProto.RegionUserInfoEntity.newBuilder();
                entity.setUserInfo(PlayerBasePb.parsePlayerBaseTempMsg(userData.getUserBaseInfo()));
                entity.setUserId(userData.getUserId());
                resp.addUserList(entity);
            }
        }
        resp.setRet(0);
        return resp;
    }

    /**
     * 区域掉落
     */
    public static DouLuoDaLuRegionInfo dropRegionInfo(CrossDouLouDaLuActivity activity, DouLuoDaLuUserData userData){
        DouLuoDaLuRegionInfo descRegion;
        if(userData.getFromRegionId() > userData.getRegionId()){
            descRegion = activity.getConfig().getFirstRegionInfo();
        }else {
            descRegion = activity.getConfig().getPreRegionInfo(userData.getRegionId());
        }
        if(descRegion == null){
            descRegion = activity.getConfig().getFirstRegionInfo();
            getLogger().error("user {} regionId {} drop error", userData.getUserId(), userData.getRegionId());
        }
        resetUserDataForChangeRegion(userData, descRegion);

        activity.checkUserRedHot(userData, activity.getAllTeamMap().get(userData.getUserId()));
        return descRegion;
    }

    /**
     * 重置玩家数据/区域变更
     * @param regionInfo 目标区域
     */
    public static void resetUserDataForChangeRegion(DouLuoDaLuUserData userData, DouLuoDaLuRegionInfo regionInfo) {
        userData.setEntryRegionTime(DateHelper.getCurrentSecond());
        userData.setFromRegionId(userData.getRegionId());
        userData.setRegionId(regionInfo.getRegionId());
        //重置玩家血量及保护时间
        userData.setTotalBlood(userData.getHunLi());
        userData.setBlood(userData.getTotalBlood());
        //清理事件统计,保留七怪保底计数
        Map<Integer, Integer> qiGuaiMap = new ConcurrentHashMap<>();

        userData.setFinishEventMap(qiGuaiMap);
        //重置事件
        userData.setEvent(new DouLuoDaLuUserEvent());
        DouLuoDaLuHelpRecordData helpRecordData = userData.getCurrentHelpRecordData();
        if(helpRecordData != null){
            updateHelpDataKillInfo(helpRecordData, -1, 0, userData);
        }
        userData.setCurrentHelpRecordData(null);
    }

    /**
     * 加魂环到玩家身上（外部要加玩家锁）
     */
    public static void addHunHuanReward(Property property, CrossDouLuoDaLuContext context){
        if (property != null && !property.isNothing()) {
            for (Map.Entry<Integer, BigInteger> entry : property.getGoods().entrySet()) {
                context.getUserData().addHunHuan(entry.getKey(), entry.getValue().intValue());
            }
            context.getActivity().calHunLi(context.getUserData(), null);
        }
    }

    /**
     * 合并玩家身上的仙草(使用一次)
     */
    public static List<Integer> mergeXianCaoAndUse(DouLuoDaLuUserData userData, List<Integer> useBuffList) {
        List<Integer> buffIdList = new ArrayList<>();
        for (Map.Entry<Integer, Integer> buffEntry : userData.getBuffMap().entrySet()) {
            if(buffEntry.getValue() > 0 && useBuffList.contains(buffEntry.getKey())){
                buffIdList.add(buffEntry.getKey());
                buffEntry.setValue(buffEntry.getValue() - 1);
                userData.setUpdateOption();
            }
        }
        return buffIdList;
    }

    /**
     * 是否有伤害buff
     */
    public static boolean hasDamageBuff(CrossDouLuoDaLuContext context){
        return hasBuff(eDouLuoDaLuBuffType.DAMAGE_BUFF.getId(), context);
    }

    /**
     * 是否有某类buff
     */
    public static boolean hasBuff(int buffId, CrossDouLuoDaLuContext context){
        Integer value = context.getUserData().getBuffMap().get(buffId);
        if(value == null){
            return false;
        }
        if(value <= 0){
            return false;
        }
        return true;
    }

    /**
     * 获取玩家伤害（附加buff加成）
     */
    public static long getHunLiDamageAddBuff(CrossDouLuoDaLuContext context, DouLuoDaLuUserData userData) {
        return CrossDouLuoDaLuMgr.hasDamageBuff(context) ? DouLuoDaLuLogic.calBuff(userData.getHunLi(), eDouLuoDaLuBuffType.DAMAGE_BUFF, context.getActivity().config) : userData.getHunLi();
    }



    /**
     * 计算森林打败怪物/真人的奖励(魂环 + 普通道具，不包括积分)
     * 返回玩家是否掉落魂环
     */
    public static boolean calBattleReward(Property hunHuanProperty, Property goodsProperty, CrossDouLuoDaLuContext context, DouLuoDaLuRegionInfo regionInfo, DouLuoDaLuEventInfo eventInfo, DouLuoDaLuUserData enemy){

        Property property = RandomWeightConfigHelper.getProperty(eventInfo.getRewards());

        if(eDouLuoDaLuEventType.PlayerEvent.getIntValue() == eventInfo.getEventType()){
            //玩家掉落魂环
            boolean userDrop = userDropHunHuan(context, enemy, regionInfo, hunHuanProperty);
            if(!"0".equals(eventInfo.getRewards())) {
                goodsProperty.addProperty(property);
            }
            return userDrop;
        }else if(eDouLuoDaLuEventType.MonsterEvent.getIntValue() == eventInfo.getEventType()){
            int hunHuanId = 0;
            for (Map.Entry<Integer, BigInteger> entry : property.getGoods().entrySet()) {
                GoodsInfo goodsInfo = GoodsMgr.getGoodsInfo(entry.getKey());
                if(goodsInfo != null && goodsInfo.getType() == eGoodsType.HunHuanItem.getValue()){
                    hunHuanId = goodsInfo.getGoodsId();
                    break;
                }
            }
            if(hunHuanId > 0){
                BigInteger remove = property.getGoods().remove(hunHuanId);
                hunHuanProperty.addProperty(hunHuanId, remove);
            }
            goodsProperty.addProperty(property);
            return false;
        }
        return false;
    }

    /**
     * 玩家掉落魂环：不足则根据区域配置的魂环进行补偿，目前固定损失数量1
     */
    private static Boolean userDropHunHuan(CrossDouLuoDaLuContext context, DouLuoDaLuUserData enemyUser, DouLuoDaLuRegionInfo regionInfo, Property hunHuanProperty) {
        List<Integer> list = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : enemyUser.getHunHuanMap().entrySet()) {
            for (int count = entry.getValue(); count > 0; count--) {
                list.add(entry.getKey());
            }
        }
        if(list.size() < context.getActivity().getConfig().FOREST_SEIZE_LIMIT){
            hunHuanProperty.addProperty(PropertyHelper.parseStringToProperty(regionInfo.getRingId() + "=1"));
            return false;
        }
        list.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                GoodsInfo g1 = TempCommonMgr.getGoodsInfo(o1);
                GoodsInfo g2 = TempCommonMgr.getGoodsInfo(o2);
                if(g1 == null || g2 == null){
                    return 0;
                }
                return g2.getParamList().get(0).compareTo(g1.getParamList().get(0));
            }
        });
        List<Integer> result = new ArrayList<>();
        int n = context.getActivity().getConfig().FOREST_SEIZE_RANDOMNUM;
        for (int i = 0; i < n; i++) {
            //前n的年限是否满足掉落限制
            if(list.get(i) < context.getActivity().getConfig().FOREST_LOWRING){
                continue;
            }
            result.add(list.get(i));
        }
        if(result.size() == 0){
            hunHuanProperty.addProperty(PropertyHelper.parseStringToProperty(regionInfo.getRingId() + "=1"));
            return false;
        }
        Random random = new Random();
        int hunHuanId = result.get(random.nextInt(result.size()));
        //扣魂环
        int oldNum = enemyUser.getHunHuanMap().get(hunHuanId);
        enemyUser.getHunHuanMap().put(hunHuanId, oldNum -1);
        enemyUser.setUpdateOption();
        context.getActivity().calHunLi(enemyUser, null);
        hunHuanProperty.addProperty(PropertyHelper.parseStringToProperty(hunHuanId + "=1"));
        return true;
    }

    /**
     * 森林打怪/真人获得积分
     */
    public static long calAddScore(long damage, long totalBlood, DouLuoDaLuEventInfo eventInfo, DouLuoDaLuRegionInfo regionInfo) {
        //区域基础分数 * 区域体力消耗
        long addScore = regionInfo.getScoreBase() * regionInfo.getEnergy();
        //事件千分比
        addScore = BigDecimal.valueOf(addScore).multiply(BigDecimal.valueOf(eventInfo.getScore())).divide(BigDecimal.valueOf(1000l), 0, BigDecimal.ROUND_UP).longValue();
        return Math.max(1, BigDecimal.valueOf(damage * addScore).divide(BigDecimal.valueOf(totalBlood), 0, BigDecimal.ROUND_DOWN).longValue());
    }

    /**
     * 阶段一：森林个人积分冲榜
     */
    public static void changeRank(DouLuoDaLuUserData userData){
//        CrossUserRank crossUserRank = new CrossUserRank();
//        crossUserRank.setUserId(userData.getUserId());
//        crossUserRank.setValue(BigInteger.valueOf(userData.getScore()));
//        crossUserRank.setType(userData.getActivityId());
//        crossUserRank.setBigRankType(eGamePlayerEventType.DouLuoDaLuPhaseOneUserScoreCrossRank.getValue());
//        crossUserRank.setUserBaseInfo(userData.getUserBaseInfo());
//        crossUserRank.setParam(String.valueOf(userData.getHunLi()));
//        ActivityRankMgr.changeActivityNewRank(userData.getActivityId(), eGamePlayerEventType.DouLuoDaLuPhaseOneUserScoreCrossRank.getValue(), crossUserRank);
        UserYRank userYRank = new UserYRank();
        userYRank.setUserId(userData.getUserId());
        userYRank.setActivityId(userData.getActivityId());
        userYRank.setGroupId(userData.getGroupId());
        userYRank.setIdKey(String.valueOf(eGamePlayerEventType.DouLuoDaLuPhaseOneUserScoreCrossRank.getValue()));
        userYRank.setValue(BigInteger.valueOf(userData.getScore()));
        userYRank.setUpdateTime(DateHelper.getCurrentTime());
        userYRank.setUserBaseInfo(userData.getUserBaseInfo());
        userYRank.setParam(String.valueOf(userData.getHunLi()));
        CrossYRankMgr.userRankChange(userYRank);
    }

    /**
     * 阶段二：魂师对决个人积分冲榜
     */
    public static void changeRank2(DouLuoDaLuUserData userData){
        if(userData.getBattleData() == null){
            return;
        }
//        CrossUserRank crossUserRank = new CrossUserRank();
//        crossUserRank.setUserId(userData.getUserId());
//        crossUserRank.setValue(BigInteger.valueOf(userData.getBattleData().getScore()));
//        crossUserRank.setType(userData.getActivityId());
//        crossUserRank.setBigRankType(eGamePlayerEventType.DouLuoDaLuPhaseTwoUserScoreCrossRank.getValue());
//        crossUserRank.setUserBaseInfo(userData.getUserBaseInfo());
//        crossUserRank.setParam(String.valueOf(userData.getHunLi()));
//        ActivityRankMgr.changeActivityNewRank(userData.getActivityId(), eGamePlayerEventType.DouLuoDaLuPhaseTwoUserScoreCrossRank.getValue(), crossUserRank);

        UserYRank userYRank = new UserYRank();
        userYRank.setUserId(userData.getUserId());
        userYRank.setActivityId(userData.getActivityId());
        userYRank.setGroupId(userData.getGroupId());
        userYRank.setIdKey(String.valueOf(eGamePlayerEventType.DouLuoDaLuPhaseTwoUserScoreCrossRank.getValue()));
        userYRank.setValue(BigInteger.valueOf(userData.getBattleData().getScore()));
        userYRank.setUpdateTime(DateHelper.getCurrentTime());
        userYRank.setUserBaseInfo(userData.getUserBaseInfo());
        userYRank.setParam(String.valueOf(userData.getHunLi()));
        CrossYRankMgr.userRankChange(userYRank);
    }

    /**
     * 阶段二：魂师对决个人积分变更
     */
    public static void changeUserScore2(CrossDouLouDaLuActivity activity, DouLuoDaLuUserData userData, long addScore, DouLuoDaLuUserData enemyData, long subScore){
        DouLuoDaLuPatronsBattleData battleData = userData.getBattleData();
        if (battleData != null) {
            //加分
            battleData.setScore(battleData.getScore() + addScore);
            //个人榜
            changeRank2(userData);
            //队伍榜
            activity.changeTeamRank(userData.getTeamId());

            //积分获得日志
            if(addScore > 0){
                CrossAutoLogMgr.add(new LogDouLuoDaLuScoreChange(activity.activityId, userData.getUserId(), activity.getConfig().SCORE_ITEM_ID_FIGHT,
                        1, addScore, battleData.getScore()));
            }
        }
        if(enemyData == null){
            return;
        }
        DouLuoDaLuPatronsBattleData enemyBattleData = enemyData.getBattleData();
        if (enemyBattleData != null){
            //减分
            enemyBattleData.setScore(enemyBattleData.getScore() - subScore);
            //个人榜
            changeRank2(enemyData);
            //队伍榜
            activity.changeTeamRank(enemyData.getTeamId());

            //积分失去日志
            if(subScore > 0){
                CrossAutoLogMgr.add(new LogDouLuoDaLuScoreChange(activity.activityId, enemyData.getUserId(), activity.getConfig().SCORE_ITEM_ID_FIGHT,
                        0, subScore, enemyBattleData.getScore()));
            }
        }
    }

    /**
     * 是否可以协助
     */
    private static boolean canHelp(DouLuoDaLuProto.DouLuoDaLuHelpActionCrossRespMsg.Builder builder, DouLuoDaLuProto.DouLuoDaLuHelpActionRespMsg.Builder clientBuilder, CrossDouLuoDaLuContext context, DouLuoDaLuHelpRecordData recordData) {
        //数据过期
        if (recordData.getKilledUserId() == -1) {
            clientBuilder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HELP_RECORD_NO_FOUND);
            builder.setRespClient(clientBuilder);
            return false;
        }
        if (recordData.getKilledUserId() != 0) {
            // 被击杀
            clientBuilder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HAS_BEEN_KILLED);
            builder.setRespClient(clientBuilder);
            return false;
        }
        if (recordData.getTargetBlood() <= 0){
            // 被击杀
            clientBuilder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HAS_BEEN_KILLED);
            builder.setRespClient(clientBuilder);
            return false;
        }
        //协助CD
        long now = System.currentTimeMillis() / 1000;
        DouLuoDaLuAttackInfo attackInfo = recordData.getHelpAttackMap().get(context.getUserId());
        if (attackInfo != null && now < (attackInfo.getAttackTime() + context.getActivity().getConfig().FOREST_ATTACK_CD)) {
            clientBuilder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_EVENT_ATTACK_CD);
            builder.setRespClient(clientBuilder);
            return false;
        }
        return true;
    }

    /**
     * 是否有事件
     */
    public static boolean hasEvent(DouLuoDaLuUserEvent event) {
        return event.getEventId() > 0 || event.getEnemyUserId() > 0;
    }

    /**
     * 队伍聊天列表
     */
    public static DouLuoDaLuProto.DouLuoDaLuTeamChatListRespMsg.Builder getTeamChatList(int activityId, long playerId) {
        DouLuoDaLuProto.DouLuoDaLuTeamChatListRespMsg.Builder builder = DouLuoDaLuProto.DouLuoDaLuTeamChatListRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData();
        if(context.ret != 0){
            builder.setRet(context.ret);
            return builder;
        }
        builder.setChatList(context.activity.getTeamChat(context.teamData.getTeamId()));
        for (DouLuoDaLuHelpRecordData recordData : context.activity.getHelpRecordDataMap(context.teamData).values()){
            //只能看到同区域的求助
            //if(recordData.getRegionId() != context.getUserData().getRegionId()){
            //    continue;
            //}
            // 当前正在求助的记录id
            builder.addRecordList(DouLuoDaLuProto.DouLuoDaLuHelpSimpleRecordEntity.newBuilder().setId(recordData.getId()).setRecordTime(recordData.getRecordTime()));
        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 查看队伍
     */
    public static DouLuoDaLuProto.DouLuoDaLuGetTeamInfoRespMsg.Builder getTeamInfo(int activityId, long playerId, int teamId) {
        DouLuoDaLuProto.DouLuoDaLuGetTeamInfoRespMsg.Builder builder = DouLuoDaLuProto.DouLuoDaLuGetTeamInfoRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData(teamId);
        if(context.getRet() != 0){
            builder.setRet(context.getRet());
            return builder;
        }
        builder.setTeamInfo(buildTeamEntity(context.getActivity(), context.getTeamData(),false));
        builder.setRet(0);
        return builder;
    }

    /**
     * 队伍列表（分页）
     */
    public static DouLuoDaLuProto.DouLuoDaLuGetTeamListRespMsg.Builder getTeamListPageBuilder(int activityId, int page, int type, long playerId, long serverId) {
        DouLuoDaLuProto.DouLuoDaLuGetTeamListRespMsg.Builder respMsg = DouLuoDaLuProto.DouLuoDaLuGetTeamListRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId);
        if(context.ret != 0){
            respMsg.setRet(context.ret);
            return respMsg;
        }
//        if(type == 0 && context.getActivity().getConfig().TEAM_JOIN_KUAFU != 1){
//            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_SUPPORT_CROSS_TEAM_UP);
//            return respMsg;
//        }
        boolean crossSupport = context.getActivity().getConfig().TEAM_JOIN_KUAFU == 1;
        List<DouLuoDaLuTeamData> list = context.activity.getTeamDataList(page, type, playerId, serverId);
        for (DouLuoDaLuTeamData teamData : list) {
          /*  if(!crossSupport && teamData.getCaptainServerId() != serverId){
                continue;
            }*/
            respMsg.addTeamList(buildTeamEntity(context.activity, teamData,false));
        }
        respMsg.setRet(0);
        return respMsg;
    }

    /**
     * 玩家积分榜单排名
     */
    public static int getUserRank(CrossDouLouDaLuActivity activity, DouLuoDaLuUserData userData, int rankType){
//        CrossActivityRankListModel rankListModel = ActivityRankMgr.getCrossActivityNewRankListModel(activity.getActivityId(), rankType);
//        int rank = -1;
//        if (rankListModel != null) {
//            rank = rankListModel.getMyRank(userData.getUserId(),userData.getUserBaseInfo().getServerId());
//        }
//        return rank;
        int activityId = activity.getActivityId();
        int groupId = activity.getGroupId();
        String idKey = String.valueOf(rankType);
        RankProto.RankListMsg.Builder rankBuilder = CrossYRankCacheMgr.getUserRankList(activityId, groupId, idKey);
        return CrossYRankCacheMgr.getUserRank(activityId, groupId, idKey, rankBuilder, userData.getUserId());
    }

    /**
     * 获取玩家在该活动的队伍排名
     * @param activityId
     * @param userId
     * @return
     */
    public static int getTeamRank(int activityId, long userId) {
        int groupId = Cross2UnionActivityGroupMgr.getGroupId(activityId, userId);

        CrossDouLouDaLuActivity douLouDaLuActivity = getActivityOrNull(activityId, groupId);
        if (douLouDaLuActivity != null) {
            DouLuoDaLuUserData userData = douLouDaLuActivity.getAllUserMap().get(userId);
            if (userData != null) {
                DouLuoDaLuTeamData team = douLouDaLuActivity.getAllTeamMap().get(userData.getTeamId());
                return getTeamRank(douLouDaLuActivity, team);
            }
        }
        return -1;
    }

    /**
     * 查询玩家（追捕、挑战）
     */
    public static DouLuoDaLuProto.DouLuoDaLuUserSearchRespMsg.Builder searchUser(int activityId, long playerId, long serverId, long userAliasId) {
        DouLuoDaLuProto.DouLuoDaLuUserSearchRespMsg.Builder builder = DouLuoDaLuProto.DouLuoDaLuUserSearchRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData();
        if(context.getRet() != 0){
            builder.setRet(context.getRet());
            return builder;
        }
        DouLuoDaLuUserData searchUserData = null;
        for (Map.Entry<Long, DouLuoDaLuUserData> userDataEntry : context.getActivity().getAllUserMap().entrySet()) {
            DouLuoDaLuUserData entryValue = userDataEntry.getValue();
            if(entryValue.getServerId() == serverId && entryValue.getUserBaseInfo().getUserAliasId() == userAliasId){
                searchUserData = entryValue;
            }
        }
        if(searchUserData == null){
            builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_NOT_FIND_USER);
            return builder;
        }else {
            if(searchUserData.getBattleData() == null){
                DouLuoDaLuPatronsBattleData battleData = context.getActivity().getBattleDataMap().get(searchUserData.getUserId());
                if(battleData != null){
                    searchUserData.setBattleData(battleData);
                }
            }
            DouLuoDaLuTeamData teamData = context.getActivity().getAllTeamMap().get(searchUserData.getTeamId());
            if(teamData == null){
                builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_PLAYER_NO_TEAM);
                return builder;
            }
            builder.setNickName(searchUserData.getUserBaseInfo().getNickName());
            builder.setRank(getUserRank(context.getActivity(), searchUserData, eGamePlayerEventType.DouLuoDaLuPhaseTwoUserScoreCrossRank.getValue()));
            builder.setUserId(searchUserData.getUserId());
            builder.setScore(searchUserData.getBattleData().getScore());
            builder.setTeamName(teamData.getName());
        }
        builder.setRet(0);
        return builder;
    }

    /**
     * 队伍榜单
     */
    private static int getTeamRank(CrossDouLouDaLuActivity douLouDaLuActivity, DouLuoDaLuTeamData team){
        int myRank = -1;
        if(team != null){
            CrossActivityTeamRankListModel rankListModel = ActivityTeamRankMgr.getCrossActivityTeamRankListModel(douLouDaLuActivity.activityId, eGamePlayerEventType.DouLuoDaLuPhaseTwoTeamScoreCrossRank.getValue(), douLouDaLuActivity.getGroupId());
            if(rankListModel != null){
                myRank = rankListModel.getMyRank(team.getTeamId(), team.getCaptainServerId());
            }
        }
        return myRank;
    }

    /**
     * 魂师对决
     */

    /**
     * 我的战斗数据
     */
    public static DouLuoDaLuProto.DouLuoDaLuGetUserBattleDataRespMsg.Builder getUserBattleMsg(int activityId, long playerId, int sendTimes, int fightTimes, int vipLv) {
        DouLuoDaLuProto.DouLuoDaLuGetUserBattleDataRespMsg.Builder resp = DouLuoDaLuProto.DouLuoDaLuGetUserBattleDataRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData().loadBattleData();
        if(context.getRet() != 0){
            resp.setRet(context.getRet());
            return resp;
        }

        //数据校验；补齐自动匹配
        DouLuoDaLuUserData nextEnemyData = null;
        DouLuoDaLuPatronsBattleData battleData = context.getBattleData();
        if(battleData.getNextEnemyUserId() == 0){
            //随机匹配一个对手，常规匹配
            List<Long> excludeList = new ArrayList<>();
            try {
                nextEnemyData = randomNextEnemyDataClose(context, excludeList);
                if(nextEnemyData != null){
                    battleData.setNextEnemyUserId(nextEnemyData.getUserId());
                }
            } catch (Exception e) {
                getLogger().error("getUserBattleMsg error. userId: {}",context.getUserData().getUserId());
            }
        }else {
            nextEnemyData = context.getActivity().getAllUserMap().get(battleData.getNextEnemyUserId());
        }

        //我方已派遣门客
        DouLuoDaLuPatronsBattle lastPatrons = getLast(battleData.getBattleList());

        DouLuoDaLuProto.DouLuoDaLuUserBattleDataTemp.Builder battleDataBuilder = DouLuoDaLuProto.DouLuoDaLuUserBattleDataTemp.newBuilder();

        //初始化待选(三选一)
        if(!battleData.isBattleEnd() && battleData.getRandomPatronsList().size() == 0){
            synchronized (battleData) {
                if(!battleData.isBattleEnd() && battleData.getRandomPatronsList().size() == 0) {
                    for (DouLuoDaLuPatronsBattleEnemy patronsBattle : randomUserThreePatrons(battleData.getEnemyBattleList())) {
                        battleData.getRandomPatronsList().add(patronsBattle.getPatronsId());
                        //待选门客(随机未战斗过的对方门客)
                        battleDataBuilder.addSelect(buildPatronsBattleData(patronsBattle));
                    }
                }
            }
        }

        //已击败对手门客数
        battleDataBuilder.setBeatNum(getBeatNum(battleData.getEnemyBattleList()));

        //对决类型
        if(battleData.getBattleType() > 1){
            battleDataBuilder.setEnemyUserId(battleData.getCaptureEnemyUserId());
        }else {
            battleDataBuilder.setEnemyUserId(battleData.getNextEnemyUserId());
        }
        battleDataBuilder.setBattleType(battleData.getBattleType());

        //对手数据
        if(battleData.getCurEnemyUserId() > 0){
            battleDataBuilder.setEnemyUserId(battleData.getCurEnemyUserId());
        }else if(nextEnemyData != null){
            battleDataBuilder.setEnemyUserId(nextEnemyData.getUserId());
        }

        long enemyId = battleDataBuilder.getEnemyUserId();
        if(enemyId > 0){
            DouLuoDaLuUserData enemy = context.getActivity().getAllUserMap().get(enemyId);

            if(battleDataBuilder.getSelectBuilderList().size() == 0){
                //待选门客(随机未战斗过的对方门客)
                for (int patronsId : battleData.getRandomPatronsList()) {
                    DouLuoDaLuPatronsBattleEnemy userPatrons = getDouLuoDaLuPatronsBattle(battleData.getEnemyBattleList(), patronsId);
                    if(userPatrons != null) {
                        battleDataBuilder.addSelect(buildPatronsBattleData(userPatrons));
                    }
                }
            }

            //对手信息（对方积分、排名）
            battleDataBuilder.setEnemyBaseInfo(getBattleUserBaseInfoMsg(context, enemy, battleData.getEnemyBattleList().size(), battleDataBuilder.getBeatNum()));

            battleDataBuilder.setEnemyInfo(PlayerBasePb.parsePlayerBaseTempMsg(enemy.getUserBaseInfo()));
        }
        //我方已派遣门客
        if(lastPatrons != null && lastPatrons.getBlood() > 0) { //存活
            battleDataBuilder.setPatrons(buildPatronsBattleData(lastPatrons));
        }

        //我方信息
        battleDataBuilder.setMyBaseInfo(getBattleUserBaseInfoMsg(context));
        resp.setSendTimes(sendTimes);
        resp.setFightTimes(fightTimes);
        resp.setOpenOneKey(battleData.getAllBattleTimes() > context.getActivity().getConfig().FIGHT_QUICKFIGHT_LIMIT_NUM && vipLv >= context.getActivity().getConfig().FIGHT_QUICKFIGHT_LIMIT_VIP);
        resp.setBattleData(battleDataBuilder);
        resp.setRet(0);
        return resp;
    }

    public static DouLuoDaLuPatronsBattleEnemy getDouLuoDaLuPatronsBattle(List<DouLuoDaLuPatronsBattleEnemy> patronsBattleList, int patronsId){
        for (DouLuoDaLuPatronsBattleEnemy patronsBattle : patronsBattleList) {
            if(patronsBattle.getPatronsId() == patronsId){
                return patronsBattle;
            }
        }
        return null;
    }

    /**
     * 派遣门客
     */
    public static DouLuoDaLuProto.DouLuoDaLuDispatchPatronsCrossRespMsg.Builder dispatchPatrons(int activityId, long playerId, int patronsId, int battleType) {
        DouLuoDaLuProto.DouLuoDaLuDispatchPatronsCrossRespMsg.Builder respMsg = DouLuoDaLuProto.DouLuoDaLuDispatchPatronsCrossRespMsg.newBuilder();
        respMsg.setPatronsId(patronsId);
        respMsg.setBattleType(battleType);
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData().loadBattleData();
        if(context.getRet() != 0){
            respMsg.setRet(context.getRet());
            return respMsg;
        }
        //校验派遣类型
        if(battleType == 1 && (context.getBattleData().getNextEnemyUserId() == 0 || context.getBattleData().getCaptureEnemyUserId() !=0 )){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_PATRONS_UN_PAIQIAN);
            return respMsg;
        }
        //追捕/挑战
        if(battleType != 1 && context.getBattleData().getCaptureEnemyUserId() == 0){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_PATRONS_UN_OUT);
            return respMsg;
        }
        if(context.getBattleData().getBattleList().size() > 0){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HAD_PATRONS_IN_BATTLE);
            return respMsg;
        }
        DouLuoDaLuUserData enemy = context.getActivity().getAllUserMap().get(context.getBattleData().getNextEnemyUserId());
        if(enemy == null){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_BATTLE_ENEMY);
            return respMsg;
        }

        //镜像血量(自己门客)
        DouLuoDaLuUserPatrons userPatrons = context.getUserData().getPatronsMap().get(patronsId);
        DouLuoDaLuPatronsBattle battle = getDouLuoDaLuPatronsBattle(context.getActivity(), context.getUserData(), userPatrons);
        context.getBattleData().getBattleList().add(battle);

        //镜像对手所有门客
        context.getBattleData().setEnemyBattleList(getDouLuoDaLuAllPatronsBattle(context.getActivity(), enemy));
        context.getBattleData().setRandomPatronsList(new ArrayList<>());

        context.getBattleData().setBattleType(battleType);
        context.getBattleData().setAllBattleTimes(1 + context.getBattleData().getAllBattleTimes());

        if(battleType == 1){
            context.getBattleData().setCurEnemyUserId(context.getBattleData().getNextEnemyUserId());
        }else {
            context.getBattleData().setCurEnemyUserId(context.getBattleData().getCaptureEnemyUserId());
        }
        respMsg.setPatrons(buildPatronsBattleData(battle));
        respMsg.setRet(0);
        return respMsg;
    }

    /**
     * 购买buff
     */
    public static DouLuoDaLuProto.DouLuoDaLuBuyBattleBuffCrossRespMsg.Builder buyBattleBuff(int activityId, long playerId, boolean firstBuy, int buyIndex, String consume) {
        DouLuoDaLuProto.DouLuoDaLuBuyBattleBuffCrossRespMsg.Builder resp = DouLuoDaLuProto.DouLuoDaLuBuyBattleBuffCrossRespMsg.newBuilder();
        resp.setConsume(consume);
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData().loadBattleData();
        if(context.getRet() != 0){
            resp.setRet(context.getRet());
            return resp;
        }
        DouLuoDaLuPatronsBattleData battleData = context.getBattleData();
        synchronized (battleData) {
            //没有派遣
            if (battleData.getBattleList().size() == 0) {
                resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_PATRONS_IN_BATTLE);
                return resp;
            }
            //已结束
            DouLuoDaLuPatronsBattle patronsBattle = getLast(battleData.getBattleList());
            if (patronsBattle.getBlood() <= 0) {
                resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_BATTLE_BEEN_END);
                return resp;
            }
            //已购买
            if (patronsBattle.getBuyBuffIdx() > 0) {
                resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HAD_BUG_BUFF);
                return resp;
            }
            int beatNum = getBeatNum(battleData.getEnemyBattleList());
            //校验首次购买参数
            if (firstBuy && beatNum > 0) {
                resp.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
                return resp;
            }
            if (!firstBuy && beatNum == 0) {
                resp.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
                return resp;
            }
            //buff生效
            patronsBattle.setBuyBuffIdx(buyIndex);
            BuffCalResult buffResult = DouLuoDaLuLogic.battleBuyBuff(context.getActivity().getConfig(), patronsBattle.getBuyBuffIdx(), patronsBattle, firstBuy);
            patronsBattle.getBuffList().add(buffResult.getBuff());
            battleData.setUpdateOption();

            resp.setPatrons(CrossDouLuoDaLuMgr.buildPatronsBattleData(patronsBattle));
            int totalAddition = 0;
            for (int i : patronsBattle.getBuffList()) {
                totalAddition += i;
            }
            resp.setAddition(totalAddition);
            resp.setRet(0);
        }
        return resp;
    }

    /**
     * 放弃购买首次buff
     */
    public static DouLuoDaLuProto.DouLuoDaLuGiveUpBuyBuffRespMsg.Builder giveUpBuyBuff(int activityId, long playerId) {
        DouLuoDaLuProto.DouLuoDaLuGiveUpBuyBuffRespMsg.Builder builder = DouLuoDaLuProto.DouLuoDaLuGiveUpBuyBuffRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData().loadBattleData();
        if(context.getRet() != 0){
            builder.setRet(context.getRet());
            return builder;
        }
        DouLuoDaLuPatronsBattleData battleData = context.getBattleData();
        //没有派遣
        if(battleData.getBattleList().size() == 0){
            builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_PATRONS_IN_BATTLE);
            return builder;
        }
        //已结束
        DouLuoDaLuPatronsBattle patronsBattle = getLast(battleData.getBattleList());
        if(patronsBattle.getBlood() <= 0){
            builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_BATTLE_BEEN_END);
            return builder;
        }
        //已购买
        if(patronsBattle.getBuyBuffIdx() > 0){
            builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HAD_BUG_BUFF);
            return builder;
        }
        if(patronsBattle.getTotalBlood() != patronsBattle.getBlood()){
            builder.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HAS_IN_BATTLE);
            return builder;
        }
        if(!patronsBattle.isGiveUpFirst()) {
            patronsBattle.setGiveUpFirst(true);
            battleData.setUpdateOption();
        }
        builder.setPatrons(CrossDouLuoDaLuMgr.buildPatronsBattleData(patronsBattle));
        builder.setRet(0);
        return builder;
    }

    /**
     * 攻击
     * (有连胜奖励时，卡攻击进度，卡结算)
     */
    public static DouLuoDaLuProto.DouLuoDaLuPatronsBattleRespMsg.Builder patronsBattle(int activityId, long playerId, int patronsId) {
        DouLuoDaLuProto.DouLuoDaLuPatronsBattleRespMsg.Builder resp = DouLuoDaLuProto.DouLuoDaLuPatronsBattleRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData().loadBattleData();
        if(context.getRet() != 0){
            resp.setRet(context.getRet());
            return resp;
        }
        DouLuoDaLuPatronsBattleData battleData = context.getBattleData();
        //没有对手
        if(battleData.getCurEnemyUserId() == 0){
            resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_BATTLE_ENEMY);
            return resp;
        }
        //没有派遣
        if(battleData.getBattleList().size() == 0){
            resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_PATRONS_IN_BATTLE);
            return resp;
        }
        //连胜奖励未领取
        DouLuoDaLuPatronsBattle patronsBattle = getLast(battleData.getBattleList());
        if(patronsBattle.isWinRewards()){
            resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HAS_WIN_REWARD_NO_RECEIVE);
            return resp;
        }
        if(patronsBattle.getBlood() <= 0){
            resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_BATTLE_BEEN_END);
            return resp;
        }
        //攻击的门客不再待选列表
        if(!battleData.getRandomPatronsList().contains(patronsId)){
            resp.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
            return resp;
        }
        //对手是否有效
        DouLuoDaLuUserData enemy = context.getActivity().getAllUserMap().get(battleData.getCurEnemyUserId());
        if(enemy == null){
            resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_ACTIVITY_USER_NO_INIT);
            return resp;
        }
        DouLuoDaLuPatronsBattleData enemyBattleData = enemy.getBattleData();
        if(enemyBattleData == null){
            resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_ACTIVITY_USER_NO_INIT);
            return resp;
        }
        //攻击门客
        DouLuoDaLuPatronsBattleEnemy enemyPatronsBattle = getDouLuoDaLuPatronsBattle(battleData.getEnemyBattleList(), patronsId);
        if(enemyPatronsBattle == null || enemyPatronsBattle.getBlood() <= 0){
            resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_ENEMY_PATRONS_BE_FAIL);
            return resp;
        }

        //追捕/挑战，积分加倍
        int battleType = battleData.getBattleType();
        int beatNum = getBeatNum(battleData.getEnemyBattleList());

        DouLuoEventHandleResult handleResult = new DouLuoEventHandleResult();
        context.getActivity().attackDamage(patronsBattle.getBlood(), enemyPatronsBattle.getBlood(), handleResult);
        patronsBattle.setBlood(patronsBattle.getBlood() - handleResult.getDamage());
        patronsBattle.setBuyBuffIdx(0);

        enemyPatronsBattle.setFightIdx(beatNum + 1);

        //特殊,自己血量为0时,不更新对手血量
        if(patronsBattle.getBlood() > 0) {
            enemyPatronsBattle.setBlood(enemyPatronsBattle.getBlood() - handleResult.getDamage());
        }
        List<DouLuoDaLuPatronsBattleEnemy> patronsList = new ArrayList<>();
        //胜、负、连胜奖励
        boolean win , end , hasWinReward = false;
        //对方换门客
        if(handleResult.isKill()){
            win = patronsBattle.getBlood() > 0 ? true : false;
            patronsList = randomUserThreePatrons(battleData.getEnemyBattleList());
            //对方没门客
            if(patronsList.size() == 0 || !win){
                end = true;
            }else {
                end = false;
            }
        }else {
            //对方还有血量，就是我方门客血量0，我方失败
            win = false;
            end = true;
        }
        List<Integer> scoreList = StringUtils.stringToIntegerList(context.getActivity().getConfig().FIGHT_SCORE_DEAL, "\\|");

        long myScore = 0;
        long enemyScore = 0;

        //积分奖励
        int addScore = scoreList.get(0);
        int subScore = scoreList.get(1);
        if(battleType > 1){
            addScore = addScore * context.getActivity().getConfig().FIGHT_FANBEI;
            subScore = subScore * context.getActivity().getConfig().FIGHT_FANBEI;
        }
        if(win){
            patronsBattle.setTimes(1 + patronsBattle.getTimes());
            //是否有连胜奖励
            hasWinReward = context.getActivity().getConfig().hasWinRewards(patronsBattle.getTimes());
            if(hasWinReward) {
                patronsBattle.setWinRewards(true);
            }

            synchronized (context.getActivity()){
                changeUserScore2(context.getActivity(), context.getUserData(), addScore, enemy, subScore);
            }

        }else {
            if(battleData.getScore() == context.getActivity().getConfig().FIGHT_PLAYER_SCORE_BEGIN){
                //失败，不加分，初始值冲榜
                synchronized (context.getActivity()){
                    changeUserScore2(context.getActivity(), context.getUserData(), 0, null, 0);
                }
            }
            resp.setAllScore(battleData.getScore());
        }
        //结算
        if(end) {
            int killNum = getBeatNum(battleData.getEnemyBattleList());
            battleData.setBattleEnd(true);
            boolean allWin = (killNum == battleData.getEnemyBattleList().size());
            battleData.setAllWin(allWin);
            if(!hasWinReward){
                synchronized (battleData) {
                    //没有连胜，直接结算
                    DouLuoDaLuProto.DouLuoDaLuBattleSettlementTem.Builder settleBuild = getSettlementBuilder(context, patronsBattle, killNum, win, enemy, allWin, null, 0);
                    resp.setSettle(settleBuild);

                    //结算日志
                    List<PatronsBlood> patronsBloodList = new ArrayList<>();
                    List<DouLuoDaLuPatronsBattleEnemy> enemyPatronsList = sort(battleData.getEnemyBattleList());
                    for (DouLuoDaLuPatronsBattleEnemy battleEnemy : enemyPatronsList) {
                        if(battleEnemy.getFightIdx() > 0){
                            patronsBloodList.add(DouLuoDaLuPb.parseDouLuoDaLuPatronsBlood(battleEnemy));
                        }
                    }
                    DouLuoDaLuProto.DouLuoDaLuBattleSettleLog.Builder logBuild = buildPatronsBattleSettleLog(patronsBloodList, patronsBattle.getBuffList(), battleData, patronsBattle, enemy, patronsBattle.getTimes(), enemyScore, myScore);
                    resp.setLog(logBuild);

                    //清理战斗数据
                    cleanBattleData(battleData);
                    if (battleType == 1) {
                        try {
                            DouLuoDaLuUserData nextEnemy = randomNextEnemyDataClose(context, new ArrayList<>());
                            if (nextEnemy != null) {
                                battleData.setNextEnemyUserId(nextEnemy.getUserId());
                            }
                        } catch (Exception e) {
                            getLogger().error("randomNextEnemyDataClose：user {}", context.getUserData().getUserId(),e);
                        }
                    }
                }
                try {
                    //处理战报
                    handleReport(patronsId, resp.getSettle().getPatronsNum(), context, enemy, scoreList, allWin, battleType);
                }catch (Exception e){
                    getLogger().error("攻击-处理战报一场：user {}", context.getUserData().getUserId(), e);
                }
            }
        }else {
            if(patronsList.size() > 0) {
                List<Integer> newList = new ArrayList<>();
                for (DouLuoDaLuPatronsBattleEnemy battleEnemy : patronsList) {
                    newList.add(battleEnemy.getPatronsId());
                }
                battleData.setRandomPatronsList(newList);
            }
        }

        //待选门客
        for (int pid : battleData.getRandomPatronsList()) {
            DouLuoDaLuPatronsBattleEnemy dpb = getDouLuoDaLuPatronsBattle(battleData.getEnemyBattleList(), pid);
            if(dpb != null) {
                resp.addSelect(buildPatronsBattleData(dpb));
            }
        }

        //我方门客
        if(battleData.getBattleList().size() > 0){
            DouLuoDaLuPatronsBattle lastPatrons = getLast(battleData.getBattleList());
            if(lastPatrons.getBlood() > 0) { //存活
                resp.setPatrons(buildPatronsBattleData(lastPatrons));
            }
        }
//        CrossDouLuoDaLuMgr.getLogger().debug("-------------{},{}", StringUtils.listToString(patronsBattle.getRewards(), "|"), patronsBattle.getAllExp());
        resp.setAllScore(battleData.getScore());
        resp.setWinTimes(patronsBattle.getTimes());
        resp.setWinReward(hasWinReward);
        resp.setWin(win);
        resp.setEnd(end);
        resp.setRet(0);
        return resp;
    }

    private static List<DouLuoDaLuPatronsBattleEnemy> sort(List<DouLuoDaLuPatronsBattleEnemy> enemyBattleList) {
        List<DouLuoDaLuPatronsBattleEnemy> result = new ArrayList<>(enemyBattleList);
        result.sort(new Comparator<DouLuoDaLuPatronsBattleEnemy>() {
            @Override
            public int compare(DouLuoDaLuPatronsBattleEnemy o1, DouLuoDaLuPatronsBattleEnemy o2) {
                return o1.getFightIdx() - o2.getFightIdx();
            }
        });
        return result;
    }

    public static int getBeatNum(List<DouLuoDaLuPatronsBattleEnemy> list){
        int beatNum = 0;
        for (DouLuoDaLuPatronsBattleEnemy patronsBattle : list) {
            if(patronsBattle.getBlood() <= 0){
                beatNum++;
            }
        }
        return beatNum;
    }

    /**
     * 处理战报
     */
    public static void handleReport(int patronsId, int patronsNum, CrossDouLuoDaLuContext context, DouLuoDaLuUserData enemy, List<Integer> scoreList, boolean allWin, int battleType) {
        //战报
        DouLuoDaLuProto.DouLuoDaLuBattleReportTemp.Builder reportData = DouLuoDaLuProto.DouLuoDaLuBattleReportTemp.newBuilder();
        reportData.setEnemyId(context.getUserId());
        reportData.setEnemyInfo(PlayerBasePb.parsePlayerBaseTempMsg(context.getUserData().getUserBaseInfo()));
        reportData.setPatronsId(patronsId);
        reportData.setPatronsNum(patronsNum);
        if(battleType > 1) {
            reportData.setScore(patronsNum * scoreList.get(1) * context.getActivity().getConfig().FIGHT_FANBEI);
        }else {
            reportData.setScore(patronsNum * scoreList.get(1));
        }
        reportData.setUserId(enemy.getUserId());
        reportData.setBattleType(battleType);
        reportData.setLogTime(System.currentTimeMillis());

        //发送区服
        DouLuoDaLuProto.DouLuoDaLuBattleReportSyncMsg.Builder sync = DouLuoDaLuProto.DouLuoDaLuBattleReportSyncMsg.newBuilder();
        sync.setActivityId(context.getActivity().getActivityId());
        sync.setReport(reportData);
        MessageHelper.sendPacket(enemy.getServerId(), enemy.getUserId(), YanQuMessageUtils.buildMessage(Protocol.S_DOU_LUO_DA_LU_SYNC_BATTLE_REPORT, sync));

        //是否上公告
        if(patronsNum >= context.getActivity().getConfig().FIGHT_LOG_BEATNUM){
            DouLuoDaLuBattleNoticeData noticeData = new DouLuoDaLuBattleNoticeData(context.getActivityId(), context.getActivity().getGroupId(), context.getUserId());
            noticeData.setAllKill(allWin);
            noticeData.setEnemyBaseInfo(enemy.getUserBaseInfo());
            noticeData.setUserBaseInfo(context.getUserData().getUserBaseInfo());
            noticeData.setPatronsId(patronsId);
            noticeData.setPatronsNum(patronsNum);
            noticeData.setLogTime(System.currentTimeMillis());
            noticeData.setBattleType(battleType);

            context.getActivity().addBattleNotice(noticeData);

            //公告跑马灯
            DouLuoDaLuProto.SyncDouLuoDaLuBattleNoticeMsg.Builder battleNoticeBuilder = DouLuoDaLuProto.SyncDouLuoDaLuBattleNoticeMsg.newBuilder();
            battleNoticeBuilder.setBattleNotice(DouLuoDaLuPb.getBattleNoticeBuilder(noticeData));
            battleNoticeBuilder.setGroupId(context.getActivity().getGroupId());
            YanQuMessage yanQuMessage = YanQuMessageUtils.buildMessage(Protocol.S_DOU_LUO_DA_LU_BATTLE_SYNC_NOTICE, battleNoticeBuilder);
            broadcastActivityServerList(context.getActivityId(), yanQuMessage);
        }
    }

    public static void broadcastActivityServerList(int activityId, YanQuMessage yanQuMessage) {
        ActivityInfo activityInfo = ActivityMgr.getActivityInfo(activityId);
        if(activityInfo == null){
            return;
        }
        for (Long serverId : activityInfo.getServerIdList()) {
            MessageHelper.sendPacket(serverId, 0, yanQuMessage);
        }
    }

    /**
     * 领取对决连胜奖励
     */
    public static DouLuoDaLuProto.DouLuoDaLuGetBattleWinRewardRespMsg.Builder getBattleWinReward(int activityId, long playerId, int patronsExp, String rewards, int winTimes, int boxId, List<String> otherRewards) {
        DouLuoDaLuProto.DouLuoDaLuGetBattleWinRewardRespMsg.Builder resp = DouLuoDaLuProto.DouLuoDaLuGetBattleWinRewardRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData().loadBattleData();
        if(context.getRet() != 0){
            resp.setRet(context.getRet());
            return resp;
        }
        DouLuoDaLuPatronsBattleData battleData = context.getBattleData();
        DouLuoDaLuPatronsBattle patronsBattle;
        synchronized (battleData) {
            if (battleData.getBattleList().size() == 0) {
                resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_PATRONS_IN_BATTLE);
                return resp;
            }
            patronsBattle = getLast(battleData.getBattleList());
            if(patronsBattle == null || !patronsBattle.isWinRewards()){
                resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_REWARD_CONDITION);
                return resp;
            }
            if(patronsBattle.getTimes() != winTimes){
                resp.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
                return resp;
            }
            patronsBattle.setWinRewards(false);
            if(patronsExp > 0){
                patronsBattle.setAllExp(patronsExp + patronsBattle.getAllExp());
                resp.setPatronsExp(patronsExp);
                resp.setPatronsId(patronsBattle.getPatronsId());
                //getLogger().debug("------patronsExp : {}", patronsExp);
            }else {
                patronsBattle.getRewards().add(rewards);
                //getLogger().debug("------rewards : {}", rewards);
                resp.setRewards(rewards);
            }
            resp.setPatronsId(patronsBattle.getPatronsId());
        }

        DouLuoDaLuUserData enemy = context.getActivity().getAllUserMap().get(battleData.getCurEnemyUserId());
        //是否可以结算
        if(battleData.isBattleEnd()){

            boolean win = patronsBattle.getBlood() > 0;
            int killNum = getBeatNum(battleData.getEnemyBattleList());

            DouLuoDaLuProto.DouLuoDaLuBattleSettlementTem.Builder settleBuild = getSettlementBuilder(context, patronsBattle, killNum, win, enemy, battleData.isAllWin(), null, 0);

            List<Integer> scoreList = StringUtils.stringToIntegerList(context.getActivity().getConfig().FIGHT_SCORE_DEAL, "\\|");
            //积分奖励
            int addScore = scoreList.get(0);
            int subScore = scoreList.get(1);
            if(battleData.getBattleType() > 1){
                addScore = addScore * context.getActivity().getConfig().FIGHT_FANBEI;
                subScore = subScore * context.getActivity().getConfig().FIGHT_FANBEI;
            }
            long myScore = battleData.getScore() - addScore * patronsBattle.getTimes();
            long enemyScore = enemy.getBattleData().getScore() + subScore * patronsBattle.getTimes();
            //结算日志
            List<PatronsBlood> patronsBloodList = new ArrayList<>();
            List<DouLuoDaLuPatronsBattleEnemy> enemyPatronsList = sort(battleData.getEnemyBattleList());
            for (DouLuoDaLuPatronsBattleEnemy battleEnemy : enemyPatronsList) {
                if(battleEnemy.getFightIdx() > 0){
                    patronsBloodList.add(DouLuoDaLuPb.parseDouLuoDaLuPatronsBlood(battleEnemy));
                }
            }
            DouLuoDaLuProto.DouLuoDaLuBattleSettleLog.Builder logBuild = buildPatronsBattleSettleLog(patronsBloodList, patronsBattle.getBuffList(), battleData, patronsBattle, enemy, patronsBattle.getTimes(), enemyScore, myScore);
            resp.setLog(logBuild);

            try {
                handleReport(patronsBattle.getPatronsId(), killNum, context, enemy, scoreList, battleData.isAllWin(), battleData.getBattleType());
            }catch (Exception e){
                getLogger().error("领取奖励-处理战报一场：user {}", context.getUserData().getUserId(), e.getCause());
            }

            //清理战斗数据
            cleanBattleData(battleData);
            resp.setSettle(settleBuild);

        }
        resp.addAllOtherRewards(otherRewards);
        resp.setBoxId(boxId);
        resp.setRet(0);
        return resp;
    }

    /**
     * 是否可以追捕/挑戰
     */
    public static DouLuoDaLuProto.DouLuoDaLuPreZhuiBuOrTiaoZhanRespMsg.Builder preZhuiBuOrTiaoZhan(int activityId, long playerId, int type, long enemyId) {
        DouLuoDaLuProto.DouLuoDaLuPreZhuiBuOrTiaoZhanRespMsg.Builder resp = DouLuoDaLuProto.DouLuoDaLuPreZhuiBuOrTiaoZhanRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData().loadBattleData();
        if(context.getRet() != 0){
            resp.setRet(context.getRet());
            return resp;
        }
        DouLuoDaLuUserData enemy = context.getActivity().getAllUserMap().get(enemyId);
        if(enemy == null){
            resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_NOT_FIND_USER);
            return resp;
        }
        //被追击的次数上限
        if(enemy.getBattleData() != null){
            if(enemy.getBattleData().getBeHitTimes() >= context.getActivity().getConfig().FIGHT_ATTACKED_MAX){
                resp.setRet(GameErrorCode.E_DOU_LUO_DA_LU_FIGHT_ATTACKED_MAX);
                return resp;
            }
        }
        resp.setRet(0);
        return resp;
    }

    /**
     * 追捕/挑战
     */
    public static DouLuoDaLuProto.DouLuoDaLuZhuiBuOrTiaoZhanCrossRespMsg.Builder zhuiBuOrTiaoZhan(int activityId, long playerId, int patronsId, long enemyId, int type, String consume) {
        DouLuoDaLuProto.DouLuoDaLuZhuiBuOrTiaoZhanCrossRespMsg.Builder respMsg = DouLuoDaLuProto.DouLuoDaLuZhuiBuOrTiaoZhanCrossRespMsg.newBuilder();
        respMsg.setType(type);
        respMsg.setPatronsId(patronsId);
        respMsg.setConsume(consume);
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData().loadBattleData();
        if(context.getRet() != 0){
            respMsg.setRet(context.getRet());
            return respMsg;
        }
        DouLuoDaLuUserData enemyData = context.getActivity().getAllUserMap().get(enemyId);
        if(enemyData == null){
            respMsg.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
            return respMsg;
        }
        if(enemyData.getBattleData() == null){
            DouLuoDaLuPatronsBattleData battleData = context.getActivity().getBattleDataMap().get(enemyData.getUserId());
            if(battleData == null){
                respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_ACTIVITY_USER_NO_INIT);
                return respMsg;
            }
            enemyData.setBattleData(battleData);
        }
        //判断是否可以挑战
        if(context.getBattleData().getCurEnemyUserId() > 0){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HAS_IN_BATTLE);
            return respMsg;
        }
        if(enemyData.getTeamId() == context.getUserData().getTeamId()){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NOT_MATCH_TEAM_MEMBER);
            return respMsg;
        }
        String contextUnionUid = context.getUnionUid();
        String enemyUnionUid = getUserActivityUnionUid(enemyData.getActivityId(), enemyData.getUserId());
        if(enemyUnionUid.equals(contextUnionUid)
                && !"".equals(contextUnionUid)){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NOT_MATCH_UNION_MEMBER);
            return respMsg;
        }
        synchronized (enemyData.getBattleData()) {
            if (enemyData.getBattleData().getBeHitTimes() >= context.getActivity().getConfig().FIGHT_ATTACKED_MAX) {
                respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_FIGHT_ATTACKED_MAX);
                return respMsg;
            }
            enemyData.getBattleData().setBeHitTimes(1 + enemyData.getBattleData().getBeHitTimes());
        }
        synchronized (context.getBattleData()){
            context.getBattleData().setCaptureEnemyUserId(enemyId);
            context.getBattleData().setCurEnemyUserId(enemyId);
            if(type == 3) {
                context.getBattleData().setLastEnemyId(enemyId);
            }
            context.getBattleData().setBattleType(type);
            context.getBattleData().setAllBattleTimes(1 + context.getBattleData().getAllBattleTimes());
            //门客直接派遣了
            //镜像血量（自己的门客）
            DouLuoDaLuUserPatrons userPatrons = context.getUserData().getPatronsMap().get(patronsId);
            DouLuoDaLuPatronsBattle battle = getDouLuoDaLuPatronsBattle(context.getActivity(), context.getUserData(), userPatrons);
            context.getBattleData().getBattleList().add(battle);

            //镜像对手所有门客
            context.getBattleData().setEnemyBattleList(getDouLuoDaLuAllPatronsBattle(context.getActivity(), enemyData));
        }

        DouLuoDaLuProto.DouLuoDaLuUserBattleDataTemp.Builder battleBuilder = DouLuoDaLuProto.DouLuoDaLuUserBattleDataTemp.newBuilder();
        battleBuilder.setEnemyUserId(enemyId);
        battleBuilder.setEnemyInfo(PlayerBasePb.parsePlayerBaseTempMsg(enemyData.getUserBaseInfo()));
        battleBuilder.setBattleType(type);

        List<DouLuoDaLuPatronsBattleEnemy> resultLit = randomUserThreePatrons(context.getBattleData().getEnemyBattleList());
        List<Integer> newList = new ArrayList<>();
        for (DouLuoDaLuPatronsBattleEnemy battleEnemy : resultLit) {
            battleBuilder.addSelect(buildPatronsBattleData(battleEnemy));
            newList.add(battleEnemy.getPatronsId());
        }
        context.getBattleData().setRandomPatronsList(newList);
        battleBuilder.setEnemyBaseInfo(getBattleUserBaseInfoMsg(context, enemyData, context.getBattleData().getEnemyBattleList().size(), 0));

        //我方门客
        DouLuoDaLuPatronsBattle lastPatrons = getLast(context.getBattleData().getBattleList());
        if(lastPatrons != null && lastPatrons.getBlood() > 0) { //存活
            battleBuilder.setPatrons(buildPatronsBattleData(lastPatrons));
        }

        battleBuilder.setMyBaseInfo(getBattleUserBaseInfoMsg(context));

        respMsg.setBattleData(battleBuilder);
        respMsg.setRet(0);
        return respMsg;
    }

    /**
     * 一键挑战：准备，拉数据回区服
     */
    public static DouLuoDaLuProto.DouLuoDaLuAutoBattleCrossRespMsg.Builder prepareOneKeyFight(int activityId, long playerId, boolean autoBuy, int buyItem, int percent, int vipLv) {
        DouLuoDaLuProto.DouLuoDaLuAutoBattleCrossRespMsg.Builder respMsg = DouLuoDaLuProto.DouLuoDaLuAutoBattleCrossRespMsg.newBuilder();
        respMsg.setActivityId(activityId);
        respMsg.setAutoBuy(autoBuy);
        respMsg.setBuyItem(buyItem);
        respMsg.setPercent(percent);
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData().loadBattleData();
        if(context.getRet() != 0){
            respMsg.setRet(context.getRet());
            return respMsg;
        }
        int now = DateHelper.getCurrentSecond();
        //活动结束前多久，不可一键条件
        if(context.getActivityInfo().getEndTime() - now < context.getActivity().getConfig().FIGHT_QUICKFIGHT_LIMIT_TIME_FINISH * DateHelper.MINUTE_SECONDS){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_END_CLOSE_NOT_ONE_KEY_FIGHT);
            return respMsg;
        }
        //1分钟内
        if(context.getBattleData().getLastOneKeyTime() > 0 && (60 > now - context.getBattleData().getLastOneKeyTime())){
            respMsg.setRet(GameErrorCode.E_REQUEST_TOO_FAST);
            return respMsg;
        }
        if(context.getBattleData().getAllBattleTimes() < context.getActivity().getConfig().FIGHT_QUICKFIGHT_LIMIT_NUM){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_ONE_KEY_FIGHT_NOT_OPEN);
            return respMsg;
        }
        if(vipLv < context.getActivity().getConfig().FIGHT_QUICKFIGHT_LIMIT_VIP){
            respMsg.setRet(GameErrorCode.E_VIP_LEVEL_NO_ENOUGH);
            return respMsg;
        }
        //没有对手
        if(context.getBattleData().getCurEnemyUserId() <= 0){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_BATTLE_ENEMY);
            return respMsg;
        }
        DouLuoDaLuUserData enemyData = context.getActivity().getAllUserMap().get(context.getBattleData().getCurEnemyUserId());
        if(enemyData == null){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_USER_DATA);
            return respMsg;
        }
        //未派遣门客
        if(context.getBattleData().getBattleList().size() == 0){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_PATRONS_IN_BATTLE);
            return respMsg;
        }
        //对方没门客
        if(enemyData.getPatronsMap().size() == 0){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_USER_NO_PATRONS_DATA);
            return respMsg;
        }
        //对决结束
        if(context.getBattleData().isBattleEnd()){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_BATTLE_BEEN_END);
            return respMsg;
        }
        DouLuoDaLuPatronsBattle patronsBattle = getLast(context.getBattleData().getBattleList());
        if(patronsBattle.getBlood() <= 0){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_BATTLE_BEEN_END);
            return respMsg;
        }
        if(patronsBattle.isWinRewards()){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HAS_WIN_REWARD_NO_RECEIVE);
            return respMsg;
        }
        context.getBattleData().setLastOneKeyTime(now);
        //我的门客
        respMsg.setPatrons(buildPatronsBattleData(patronsBattle));

        //对方存活门客
        List<DouLuoDaLuProto.DouLuoDaLuPatronsBattleDataTemp> liveList = new ArrayList<>();

        //对方战败门客
        for (DouLuoDaLuPatronsBattleEnemy battle : context.getBattleData().getEnemyBattleList()) {
            if(battle.getBlood() <= 0){
                respMsg.addDeath(battle.getPatronsId());
                continue;
            }
            liveList.add(buildPatronsBattleData(battle).build());
        }
        if(liveList.size() == 0){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_BATTLE_BEEN_END);
            return respMsg;
        }
        respMsg.setThisTime(now);
        context.getBattleData().setLastOneKeyTime(now);
        respMsg.addAllEnemyPatrons(liveList);
        respMsg.setRet(0);
        return respMsg;
    }

    /**
     * 一键挑战-结算
     */
    public static DouLuoDaLuProto.DouLuoDaLuAutoBattleSettleRespMsg.Builder oneKeyBattleSettle(int activityId, long playerId, int thisTime, boolean win, int patronsId, int patronsNum,
                  List<String> rewards, int patronsExp, String consume, List<PatronsBlood> battleEnemyList, List<Integer> buff, List<Integer> startBuyIdx) {
        DouLuoDaLuProto.DouLuoDaLuAutoBattleSettleRespMsg.Builder respMsg = DouLuoDaLuProto.DouLuoDaLuAutoBattleSettleRespMsg.newBuilder();
        respMsg.setConsume(consume);
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData().loadBattleData();
        if(context.getRet() != 0){
            respMsg.setRet(context.getRet());
            return respMsg;
        }
        DouLuoDaLuPatronsBattleData battleData = context.getBattleData();
        if(thisTime != battleData.getLastOneKeyTime()){
            respMsg.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
            return respMsg;
        }
        if(battleData.isBattleEnd()){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_BATTLE_BEEN_END);
            return respMsg;
        }
        //未派遣门客
        if(battleData.getBattleList().size() == 0){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_NO_PATRONS_IN_BATTLE);
            return respMsg;
        }
        DouLuoDaLuPatronsBattle patronsBattle = getLast(battleData.getBattleList());
        if(patronsBattle == null || patronsBattle.getBlood() <= 0){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_BATTLE_BEEN_END);
            return respMsg;
        }
        if(patronsBattle.getPatronsId() != patronsId){
            respMsg.setRet(GameErrorCode.E_REQUEST_ARGUMENT_ERROR);
            return respMsg;
        }
        if(patronsBattle.isWinRewards()){
            respMsg.setRet(GameErrorCode.E_DOU_LUO_DA_LU_HAS_WIN_REWARD_NO_RECEIVE);
            return respMsg;
        }
        DouLuoDaLuUserData enemy = context.getActivity().getAllUserMap().get(battleData.getCurEnemyUserId());

        //积分，按胜利场次/击败门客数
        List<Integer> scoreList = StringUtils.stringToIntegerList(context.getActivity().getConfig().FIGHT_SCORE_DEAL, "\\|");

        DouLuoDaLuPatronsBattleEnemy lastEnemyPatrons = getLastEnemy(battleData.getEnemyBattleList());
        int beginDeathNum;
        if(lastEnemyPatrons == null){
            beginDeathNum = 0;
        }else {
            beginDeathNum = getBeatNum(battleData.getEnemyBattleList());
        }

        int winTimes = patronsNum + beginDeathNum;
        boolean allWin = (winTimes == battleData.getEnemyBattleList().size());
        //type 2 是追捕/3挑战，积分加倍
        int battleType = battleData.getBattleType();
        int addScore = scoreList.get(0);
        int subScore = scoreList.get(1);
        if(battleType > 1){
            addScore = addScore * context.getActivity().getConfig().FIGHT_FANBEI;
            subScore = subScore * context.getActivity().getConfig().FIGHT_FANBEI;
        }
        try {
            handleReport(patronsId, winTimes, context, enemy, scoreList, allWin, battleData.getBattleType());
        }catch (Exception e){
            getLogger().error("一键挑战结算-处理战报一场：user {}", context.getUserData().getUserId(), e.getCause());
        }

        //本场战斗之前的积分
        long myScore = 0;
        long enemyScore = 0;

        respMsg.setScore(addScore * patronsNum);

        synchronized (context.getActivity()){
            changeUserScore2(context.getActivity(), context.getUserData(), addScore * patronsNum, enemy, subScore * patronsNum);
        }

        patronsBattle.setAllExp(patronsExp + patronsBattle.getAllExp());
        Property oldRewards = new Property();
        for (String reward : patronsBattle.getRewards()) {
            oldRewards.addProperty(PropertyHelper.parseStringToProperty(reward));
        }
        patronsBattle.getRewards().addAll(rewards);

        DouLuoDaLuProto.DouLuoDaLuBattleSettlementTem.Builder settleBuild = getSettlementBuilder(context, patronsBattle, winTimes, win, enemy, allWin, rewards, patronsExp);
        settleBuild.setOldPatronsExp(patronsBattle.getAllExp() - patronsExp);
        settleBuild.setOldRewards(PropertyHelper.parsePropertyToString(oldRewards));
        respMsg.setSettle(settleBuild);

        //结算日志
        List<PatronsBlood> allPatronsBloodList = new ArrayList<>();
        List<DouLuoDaLuPatronsBattleEnemy> fightList = sort(battleData.getEnemyBattleList());
        for (DouLuoDaLuPatronsBattleEnemy battleEnemy : fightList) {
            if(battleEnemy.getFightIdx() > 0){
                allPatronsBloodList.add(DouLuoDaLuPb.parseDouLuoDaLuPatronsBlood(battleEnemy));
            }
        }
        patronsBattle.getBuffList().addAll(buff);
        allPatronsBloodList.addAll(battleEnemyList);
        DouLuoDaLuProto.DouLuoDaLuBattleSettleLog.Builder log = buildPatronsBattleSettleLog(allPatronsBloodList, patronsBattle.getBuffList(), battleData, patronsBattle, enemy, winTimes, enemyScore, myScore);
        log.setOldPatronsExp(patronsBattle.getAllExp() - patronsExp);
        log.setOldRewards(PropertyHelper.parsePropertyToString(oldRewards));
        respMsg.setLog(log);

        //战斗动画
        //我方门客
        DouLuoDaLuPatronsBattle lastPatrons = getLast(context.getBattleData().getBattleList());
        if(lastPatrons != null) {
            DouLuoDaLuProto.DouLuoDaLuPatronsBattleDataTemp.Builder myPatrons = buildPatronsBattleData(lastPatrons);
            myPatrons.clearBuff();
            myPatrons.addAllBuff(buff);
            respMsg.setMyPatrons(myPatrons);
        }
        //对方门客
        for (PatronsBlood enemyPatronsBlood : battleEnemyList) {
            for (DouLuoDaLuPatronsBattleEnemy enemyPatrons : battleData.getEnemyBattleList()) {
                if(enemyPatronsBlood.getPatronsId() == enemyPatrons.getPatronsId()){
                    DouLuoDaLuProto.DouLuoDaLuPatronsBattleDataTemp.Builder patronsBuild = buildPatronsBattleData(enemyPatrons);
                    respMsg.addEnemyPatrons(patronsBuild);
                    break;
                }
            }
        }

        //清理数据
        battleData.setLastOneKeyTime(0);
        cleanBattleData(context.battleData);
        respMsg.setPatronsNum(patronsNum);
        respMsg.setWin(win);
        respMsg.addAllStartBuyIdx(startBuyIdx);
        respMsg.setPatronsId(patronsId);
        respMsg.setPatronsExp(patronsExp);
        Property winReward = new Property();
        for (String reward : rewards) {
            winReward.addProperty(PropertyHelper.parseStringToProperty(reward));
        }
        respMsg.setWinRewards(PropertyHelper.parsePropertyToString(winReward));
        respMsg.setRet(0);
        return respMsg;
    }

    /**
     * 魂师对决结算日志
     */
    private static DouLuoDaLuProto.DouLuoDaLuBattleSettleLog.Builder buildPatronsBattleSettleLog(List<PatronsBlood> battleEnemyList, List<Integer> buff,
                            DouLuoDaLuPatronsBattleData battleData, DouLuoDaLuPatronsBattle patronsBattle, DouLuoDaLuUserData enemy, int winTimes, long enemyScore, long myScore) {
        //日志
        DouLuoDaLuProto.DouLuoDaLuBattleSettleLog.Builder log = DouLuoDaLuProto.DouLuoDaLuBattleSettleLog.newBuilder();
        log.setHunLi(patronsBattle.getHunLi());
        log.addAllBuff(buff);
        log.setEnemyUserId(enemy.getUserId());
        log.setEnemyServerId(enemy.getServerId());
        log.setEnemyScore(enemyScore);
        log.setEnemyPatronsNum(battleData.getEnemyBattleList().size());
        long enemyHunLi = 0;
        for (DouLuoDaLuPatronsBattleEnemy patronsBattleEnemy : battleData.getEnemyBattleList()) {
            enemyHunLi += patronsBattleEnemy.getHunLi();
        }
        log.setEnemyHunLi(enemyHunLi);
        log.setWinTimes(winTimes);
        log.setMyScore(myScore);
        for (PatronsBlood battleEnemy : battleEnemyList) {
            log.addPatrons(DouLuoDaLuPb.buildDouLuoDaLuBattlePatronsBlood(battleEnemy));
        }
        return log;
    }

    /**
     * 随机玩家
     */
    private static DouLuoDaLuUserData randomNextEnemyDataClose(CrossDouLuoDaLuContext context, List<Long> excludeList) {
        List<DouLuoDaLuUserData> list = new ArrayList<>();
        String contextUnionUid = context.getUnionUid();
//        CrossDouLuoDaLuMgr.getLogger().debug("-----------sort------------");
//        CrossDouLuoDaLuMgr.getLogger().debug("my {},{}", context.getUserData().getBattleData().getScore(), context.getUserData().getHunLi());
        for (Map.Entry<Long, DouLuoDaLuUserData> entry : context.getActivity().getAllUserMap().entrySet()) {
            if(excludeList.contains(entry.getKey())){
                continue;
            }
            if(entry.getValue().getTeamId() == 0){
                continue;
            }
            if(entry.getValue().getBattleData() == null){
                continue;
            }
            if(entry.getValue().getTeamId() == context.getUserData().getTeamId()){
                continue;
            }
            if(getUserActivityUnionUid(entry.getValue().getActivityId(), entry.getValue().getUserId()).equals(contextUnionUid)
                    && !"".equals(contextUnionUid)){
                continue;
            }
            list.add(entry.getValue());
        }
        list.sort(new Comparator<DouLuoDaLuUserData>() {
            @Override
            public int compare(DouLuoDaLuUserData o1, DouLuoDaLuUserData o2) {
                if(o1.getBattleData() != null && o2.getBattleData() != null){
                    long l = Math.abs(o1.getBattleData().getScore() - context.getUserData().getBattleData().getScore())
                            - Math.abs(o2.getBattleData().getScore() - context.getUserData().getBattleData().getScore());
                    if(l > 0){
                        return 1;
                    }
                    if(l < 0){
                        return -1;
                    }
                }
                long l = Math.abs(o1.getHunLi() - context.getUserData().getHunLi()) - Math.abs(o2.getHunLi() - context.getUserData().getHunLi());
                if(l > 0){
                    return 1;
                }
                if(l < 0){
                    return -1;
                }
                return 0;
            }
        });
        if(list.size() == 0){
            return null;
        }
//        for (DouLuoDaLuUserData data : list) {
//            CrossDouLuoDaLuMgr.getLogger().debug("result {},{}", data.getBattleData().getScore(), data.getHunLi());
//        }
        int num = Math.min(context.getActivity().getConfig().FIGHT_MATCH_NUM, list.size());
        if(num == 0 && list.size() > 0){
            return list.get(0);
        }
        Random random = new Random();
        int idx = random.nextInt(num);
//        CrossDouLuoDaLuMgr.getLogger().debug("FIGHT_MATCH_NUM {}", context.getActivity().getConfig().FIGHT_MATCH_NUM);
//        CrossDouLuoDaLuMgr.getLogger().debug("idx {}", idx);
        return list.get(idx);
    }

    /**
     * 随机对手未出战中的三个门客
     */
    private static List<DouLuoDaLuPatronsBattleEnemy> randomUserThreePatrons(List<DouLuoDaLuPatronsBattleEnemy> all) {
        List<DouLuoDaLuPatronsBattleEnemy> resultLit = new ArrayList<>();
        List<DouLuoDaLuPatronsBattleEnemy> selectList = new ArrayList<>();
        for (DouLuoDaLuPatronsBattleEnemy patronsBattle : all) {
            //排除已击败
            if(patronsBattle.getBlood() <= 0){
                continue;
            }
            selectList.add(patronsBattle);
        }
        if(selectList.size() <= 3){
            return selectList;
        }
        Random random = new Random();
        while(resultLit.size() < 3 && selectList.size() > 0){
            int idx = random.nextInt(selectList.size());
            resultLit.add(selectList.remove(idx));
        }
        return resultLit;
    }

    /**
     * 门客列表
     */
    public static DouLuoDaLuProto.DouLuoDaLuGetPatronsListRespMsg.Builder patronsList(int activityId, long playerId) {
        DouLuoDaLuProto.DouLuoDaLuGetPatronsListRespMsg.Builder respMsg = DouLuoDaLuProto.DouLuoDaLuGetPatronsListRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData();
        if(context.getRet() != 0){
            respMsg.setRet(context.getRet());
            return respMsg;
        }
        for (Map.Entry<Integer, DouLuoDaLuUserPatrons> patronsEntry : context.getUserData().getPatronsMap().entrySet()) {
            respMsg.addPatronsList(parseDouLuoDaLuPatronsDetailTemp(patronsEntry.getValue()));
        }

        respMsg.setRet(0);
        return respMsg;
    }

    private static void cleanBattleData(DouLuoDaLuPatronsBattleData battleData) {
        battleData.setEnemyBattleList(new ArrayList<>());
        battleData.setRandomPatronsList(new ArrayList<>());
        battleData.setBattleList(new ArrayList<>());
        battleData.setBattleEnd(false);
        battleData.setAllWin(false);
        if(battleData.getBattleType() == 1){
            battleData.setNextEnemyUserId(0);
        }
        battleData.setCaptureEnemyUserId(0);
        battleData.setBattleType(0);
        battleData.setCurEnemyUserId(0);
    }

    private static DouLuoDaLuProto.DouLuoDaLuBattleSettlementTem.Builder getSettlementBuilder(CrossDouLuoDaLuContext context, DouLuoDaLuPatronsBattle patronsBattle,
                                   int killNum, boolean win, DouLuoDaLuUserData enemy, boolean allWin, List<String> winRewards, int patronsExp) {
        DouLuoDaLuProto.DouLuoDaLuBattleSettlementTem.Builder settleBuild = DouLuoDaLuProto.DouLuoDaLuBattleSettlementTem.newBuilder();
        //击败门客数
        settleBuild.setPatronsNum(killNum);
        settleBuild.setBattleType(context.getBattleData().getBattleType());
        settleBuild.setAllKill(allWin);

        //道具奖励
        List<String> endRewardList = StringUtils.stringToStringList(context.getActivity().getConfig().FIGHT_REWARD_END, "\\|");
        settleBuild.setRewards(win ? endRewardList.get(0) : endRewardList.get(1));
        settleBuild.setEnemyInfo(PlayerBasePb.parsePlayerBaseTempMsg(enemy.getUserBaseInfo()));
        settleBuild.setPatronsId(patronsBattle.getPatronsId());
        //历史奖励
        Property allProperty = new Property();
        if(winRewards != null || patronsExp > 0){
            //一键挑战
            if(winRewards != null){
                for (String winReward : winRewards) {
                    allProperty.addProperty(PropertyHelper.parseStringToProperty(winReward));
                }
            }
            settleBuild.setAllPatronsExp(patronsExp);
        }else {
            for (String reward : patronsBattle.getRewards()) {
                allProperty.addProperty(PropertyHelper.parseStringToProperty(reward));
            }
            settleBuild.setAllPatronsExp(patronsBattle.getAllExp());
        }
        //结算奖励加到历史奖励中
        allProperty.addProperty(PropertyHelper.parseStringToProperty(settleBuild.getRewards()));
        settleBuild.setAllRewards(PropertyHelper.parsePropertyToString(allProperty));
        return settleBuild;
    }

    /**
     * 上传试炼抽奖宝库  日志
     */
    public static void uploadBaoKuDrawRecord(int activityId, long playerId, int goodsId, int type) {
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId);
        if(context.getRet() == 0){
            context.getActivity().uploadRecord(goodsId, context.getUserData(), type);
        }
    }

    public static DouLuoDaLuProto.CrossDouLuoDaLuDrawHideBoxRespMsg.Builder drawHideBox(int activityId, long userId) {
        DouLuoDaLuProto.CrossDouLuoDaLuDrawHideBoxRespMsg.Builder respMsg = DouLuoDaLuProto.CrossDouLuoDaLuDrawHideBoxRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, userId).loadTeamData().loadBattleData();
        if(context.getRet() != 0){
            respMsg.setIsHide(false);
            respMsg.setRet(context.getRet());
            return respMsg;
        }
        respMsg.setIsHide(context.getActivity().drawHideBox());
        respMsg.setRet(0);
        return respMsg;
    }

    private static DouLuoDaLuProto.DouLuoDaLuBattleUserBaseInfoTemp.Builder getBattleUserBaseInfoMsg(CrossDouLuoDaLuContext context, DouLuoDaLuUserData enemy, int allPatronsNum, int beatNum) {
        DouLuoDaLuProto.DouLuoDaLuBattleUserBaseInfoTemp.Builder enemyBaseInfo = DouLuoDaLuProto.DouLuoDaLuBattleUserBaseInfoTemp.newBuilder();
        DouLuoDaLuPatronsBattleData enemyBattleData = enemy.getBattleData();
        if(enemyBattleData == null){
            enemyBattleData = context.getActivity().getBattleDataMap().get(enemy.getUserId());
            enemy.setBattleData(enemyBattleData);
        }
        if(enemyBattleData != null){
            enemyBaseInfo.setScore(enemyBattleData.getScore());
            enemyBaseInfo.setRank(getUserRank(context.getActivity(), enemy, eGamePlayerEventType.DouLuoDaLuPhaseTwoUserScoreCrossRank.getValue()));
            DouLuoDaLuTeamData teamData = context.getActivity().getAllTeamMap().get(enemy.getTeamId());
            if(teamData != null) {
                enemyBaseInfo.setTeamName(teamData.getName());
                enemyBaseInfo.setTeamRank(getTeamRank(context.getActivity(), teamData));
            }
            List<Integer> buffIdList = context.getActivity().mergeHunHuan(enemy);
            enemyBaseInfo.setFixedAddition(context.getActivity().getHunLiFixedAddition(buffIdList));
            enemyBaseInfo.setAddition(context.getActivity().getHunLiMilliAddition(buffIdList));
            enemyBaseInfo.setAllPatrons(allPatronsNum);
            enemyBaseInfo.setAttackPatrons(beatNum);
        }
        enemyBaseInfo.addAllHunHuan(DouLuoDaLuPb.parseUserItemTemp(enemy.getHunHuanMap()));
        enemyBaseInfo.setHunLi(enemy.getHunLi());
        enemyBaseInfo.setAllPatronsEarn(enemy.getAllPatronsEarn());
        return enemyBaseInfo;
    }

    private static DouLuoDaLuProto.DouLuoDaLuBattleUserBaseInfoTemp.Builder getBattleUserBaseInfoMsg(CrossDouLuoDaLuContext context) {
        DouLuoDaLuProto.DouLuoDaLuBattleUserBaseInfoTemp.Builder myBaseInfo = DouLuoDaLuProto.DouLuoDaLuBattleUserBaseInfoTemp.newBuilder();
        myBaseInfo.setScore(context.getBattleData().getScore());
        myBaseInfo.setRank(getUserRank(context.getActivity(), context.getUserData(), eGamePlayerEventType.DouLuoDaLuPhaseTwoUserScoreCrossRank.getValue()));
        myBaseInfo.setTeamName(context.getTeamData().getName());
        List<Integer> buffIdList = context.getActivity().mergeHunHuan(context.getUserData());
        myBaseInfo.setFixedAddition(context.getActivity().getHunLiFixedAddition(buffIdList));
        myBaseInfo.setAddition(context.getActivity().getHunLiMilliAddition(buffIdList));
        myBaseInfo.setTeamRank(getTeamRank(context.getActivity(), context.getTeamData()));
        myBaseInfo.setHunLi(context.getUserData().getHunLi());
        myBaseInfo.setAllPatronsEarn(context.getUserData().getAllPatronsEarn());
        myBaseInfo.setAllPatrons(context.getUserData().getPatronsMap().size());
        myBaseInfo.addAllHunHuan(DouLuoDaLuPb.parseUserItemTemp(context.getUserData().getHunHuanMap()));
        return myBaseInfo;
    }


    /**
     * 获取森林事件日志
     */
    public static DouLuoDaLuProto.DouLuoDaLuEventNoticeRespMsg.Builder eventNoticeList(int activityId, long playerId) {
        DouLuoDaLuProto.DouLuoDaLuEventNoticeRespMsg.Builder resp = DouLuoDaLuProto.DouLuoDaLuEventNoticeRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData().loadBattleData();
        if(context.getRet() != 0){
            resp.setRet(context.getRet());
            return resp;
        }
        List<DouLuoDaLuEventNoticeData> list = context.getActivity().getEventNoticeDataList();
        int size = list.size();
        for (int i = 0; i < size; i++) {
            if(i >= context.getActivity().getConfig().FIGHT_LOG_LIMIT){
                break;
            }
            DouLuoDaLuEventNoticeData noticeData = list.get(i);
            DouLuoDaLuProto.DouLuoDaLuEventNoticeTemp.Builder builder = DouLuoDaLuPb.getEventNoticeBuilder(noticeData);
            resp.addNotify(builder.build());
        }
        resp.setRet(0);
        return resp;
    }

    /**
     * 获取对决公告日志
     */
    public static DouLuoDaLuProto.DouLuoDaLuBattleNoticeRespMsg.Builder battleNoticeList(int activityId, long playerId) {
        DouLuoDaLuProto.DouLuoDaLuBattleNoticeRespMsg.Builder resp = DouLuoDaLuProto.DouLuoDaLuBattleNoticeRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData().loadBattleData();
        if(context.getRet() != 0){
            resp.setRet(context.getRet());
            return resp;
        }
        List<DouLuoDaLuBattleNoticeData> list = context.getActivity().getBattleNoticeDataList();
        int size = list.size();
        int allTimes = context.getActivity().getConfig().FIGHT_ATTACKED_MAX;
        for (int i = 0; i < size; i++) {
            if(i >= context.getActivity().getConfig().FIGHT_LOG_LIMIT){
                break;
            }
            DouLuoDaLuBattleNoticeData noticeData = list.get(i);
            DouLuoDaLuProto.DouLuoDaLuBattleNoticeTemp.Builder builder = DouLuoDaLuPb.getBattleNoticeBuilder(noticeData);
            //玩家剩余挑战次数
            DouLuoDaLuPatronsBattleData battleData = context.getActivity().getBattleDataMap().get(builder.getUserId());
            if(battleData != null){
                builder.setBeatTime(allTimes - battleData.getBeHitTimes());
            }
            resp.addReport(builder.build());
        }
        resp.setLastAttack(context.getBattleData().getLastEnemyId());
        resp.setRet(0);
        return resp;
    }

    /**
     * 队友协助日志
     */
    public static DouLuoDaLuProto.DouLuoDaLuHelpRecordListRespMsg.Builder getHelpRecordList(int activityId, long playerId) {
        DouLuoDaLuProto.DouLuoDaLuHelpRecordListRespMsg.Builder respMsg = DouLuoDaLuProto.DouLuoDaLuHelpRecordListRespMsg.newBuilder();
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData().loadBattleData();
        if(context.getRet() != 0){
            respMsg.setRet(context.getRet());
            return respMsg;
        }
        // 队友互助
        Set<DouLuoDaLuHelpRecordData> set = new HashSet<>();
        // 正在求助
        Map<Long, DouLuoDaLuHelpRecordData> helpRecordMap = context.getActivity().getHelpRecordDataMap(context.getTeamData());
        if(helpRecordMap != null){
            for (Map.Entry<Long, DouLuoDaLuHelpRecordData> recordDataEntry : helpRecordMap.entrySet()) {
                set.add(recordDataEntry.getValue());
            }
        }
        // 未领取的
        List<DouLuoDaLuHelpRecordData> userRecordList = context.getActivity().getHelpRecordDataMap().get(context.getUserId());
        if(userRecordList != null){
            int size = userRecordList.size();
            for (int i = 0; i < size; i++) {
                DouLuoDaLuHelpRecordData recordData = userRecordList.get(i);
                //我的求助，未领取
                if(recordData.getUserId() == context.getUserId() && recordData.getKilledUserId() > 0 && !recordData.isReceived()) {
                    set.add(recordData);
                }
                //协助过，队友未领取
                if(recordData.getKilledUserId() == context.getUserId() && !recordData.isReceived()){
                    set.add(recordData);
                }
            }
        }
        for (DouLuoDaLuHelpRecordData item : set){
            respMsg.addHelpRecord(buildHelpRecord(context, item));
        }
        respMsg.setCanHelpTimes(getCanHelpTimes(context.getUserData(),context.getActivity().config));
        respMsg.setRet(0);
        return respMsg;
    }

    private static int getCanHelpTimes(DouLuoDaLuUserData userData, DouLuoDaLuConfig config) {
        int curHelpTimes = userData.getHelpTimes();
        int consumeEnergy = userData.getUseEnergy();
        int addTimes = 0;
        if (config.helpConsumeHp > 0) {
            addTimes = consumeEnergy / config.helpConsumeHp * config.helpAddTimes;
        }
        int helpTimes = config.initHelpTimes + addTimes - curHelpTimes;
        if (helpTimes > 0) {
            return helpTimes;
        }
        return 0;
    }


    /**
     * 添加森林事件日志
     */
    public static void addEventNotice(int activityId, long playerId, DouLuoDaLuEventNoticeData noticeData) {
        CrossDouLuoDaLuContext context = CrossDouLuoDaLuContext.initContext(activityId, playerId).loadTeamData();
        if(context.getRet() != 0){
           return;
        }
        noticeData.setActivityId(activityId);
        noticeData.setUserId(playerId);
        noticeData.setGroupId(context.getActivity().getGroupId());
        noticeData.setRegionId(context.getUserData().getRegionId());
        noticeData.setUserBaseInfo(context.getUserData().getUserBaseInfo());
        noticeData.setLogTime(System.currentTimeMillis());
        noticeData.setInsertOption();
        context.getActivity().addEventNotice(noticeData);

        //区服上传的现金\宝箱  公告
        context.getActivity().syncEventLog(context.getUserData(), noticeData);
    }

    /**
     * 处理森林事件-攻击玩家的广播
     */
    public static void handleAttackPlayerEventBroadcast(DouLuoEventHandleResult handleResult, CrossDouLuoDaLuContext context, Set<DouLuoDaLuUserData> markEnemySet, DouLuoDaLuUserData enemyUserData, int now) {
        if(handleResult.isKill()){
            //标记对手的都得先拿对手玩家锁

                for (DouLuoDaLuUserData userData : markEnemySet) {
                    DouLuoDaLuUserEvent userEvent = userData.getEvent();
                    if (userData != context.getUserData()) {
                        if(userEvent.getEventType() == eDouLuoDaLuEventType.PlayerEvent.getIntValue() && userEvent.getEnemyUserId() == enemyUserData.getUserId()) {

                            userData.setEvent(new DouLuoDaLuUserEvent());

                            DouLuoDaLuProto.BroadcastDouLuoDaLuEventInfo.Builder builder = DouLuoDaLuProto.BroadcastDouLuoDaLuEventInfo.newBuilder();
                            builder.setType(2);
                            MessageHelper.sendPacket(userData.getServerId(), userData.getUserId(), YanQuMessageUtils.buildMessage(ClientProtocol.U_DOU_LUO_DA_LU_BROADCAST_EVENT_INFO, builder));
                        }
                        DouLuoDaLuHelpRecordData helpRecordData = userData.getCurrentHelpRecordData();
                        if(helpRecordData != null && helpRecordData.getTargetId() == enemyUserData.getUserId()){
                            updateHelpDataKillInfo(helpRecordData, -1, 0, userData);
                        }
                    }
                }

        }else {
            DouLuoDaLuProto.BroadcastDouLuoDaLuEventInfo.Builder builder = DouLuoDaLuProto.BroadcastDouLuoDaLuEventInfo.newBuilder();
            builder.setType(0);
            builder.setUserId(enemyUserData.getUserId());
            builder.setRemainBlood(handleResult.getBlood());
            builder.setDamage(handleResult.getDamage());

                for (DouLuoDaLuUserData userData : markEnemySet) {
                    if (userData != context.getUserData()) {
                        DouLuoDaLuUserEvent userEvent = userData.getEvent();
                        MessageHelper.sendPacket(userData.getServerId(), userData.getUserId(), YanQuMessageUtils.buildMessage(ClientProtocol.U_DOU_LUO_DA_LU_BROADCAST_EVENT_INFO, builder));

                        DouLuoDaLuHelpRecordData helpRecordData = userData.getCurrentHelpRecordData();
                        if(helpRecordData != null && helpRecordData.getTargetId() == enemyUserData.getUserId()){
                            helpRecordData.setTargetBlood(enemyUserData.getBlood());
                            //队友的标记需要同步我的攻击时间
                            if(userData.getTeamId() == context.getUserData().getTeamId()){
                                updateAttackInfo(context.getUserData(), helpRecordData, handleResult.getDamage(), now);
                            }
                        }
                        if(userEvent.getEventType() == eDouLuoDaLuEventType.PlayerEvent.getIntValue() && userEvent.getEnemyUserId() == enemyUserData.getUserId()){
                            userEvent.setBlood(enemyUserData.getBlood());
                        }
                    }
                }

            MessageHelper.sendPacket(enemyUserData.getServerId(), enemyUserData.getUserId(), YanQuMessageUtils.buildMessage(ClientProtocol.U_DOU_LUO_DA_LU_BROADCAST_EVENT_INFO, builder));
        }
    }

    /**
     * 被击败提示
     */
    public static void pushEnemyTip(CrossDouLuoDaLuContext context, DouLuoEventHandleResult handleResult, DouLuoDaLuUserData enemyUserData, Property hunHuan, boolean enemyLost, int attackType) {
        DouLuoDaLuEnemyTip enemyTip = new DouLuoDaLuEnemyTip();
        enemyTip.setDamage(handleResult.getDamage());
        enemyTip.setEnemyId(context.getUserData().getUserId());
        enemyTip.setRegionId(enemyUserData.getRegionId());
        enemyTip.setAttackType(attackType);
        if (enemyLost) {
            enemyTip.setRobedProperty(PropertyHelper.parsePropertyToString(hunHuan));
        }
        if(!enemyUserData.isEntry()) {
            enemyUserData.getEnemyTipList().add(enemyTip);
            enemyUserData.setUpdateOption();
        }else {
            List<DouLuoDaLuEnemyTip> list = new ArrayList<>();
            list.addAll(enemyUserData.getEnemyTipList());
            if(enemyUserData.getEnemyTipList().size() > 0){
                enemyUserData.setEnemyTipList(new ArrayList<>());
            }
            list.add(enemyTip);
            pushEnemyTipMsg(context, enemyUserData, list);
        }
    }

    /**
     * 仇人提示
     */
    public static void pushEnemyTipMsg(CrossDouLuoDaLuContext context, DouLuoDaLuUserData enemyUserData, List<DouLuoDaLuEnemyTip> tipList) {
        DouLuoDaLuProto.DouLuoDaLuOnLinePushTemp.Builder tempBuilder =  DouLuoDaLuProto.DouLuoDaLuOnLinePushTemp.newBuilder();
        tempBuilder.setType(2);
        tempBuilder.addUser(enemyUserData.getUserId());
        List<DouLuoDaLuProto.DouLuoDaLuUserItemInfoTemp> hunHuan = DouLuoDaLuPb.parseUserItemTemp(enemyUserData.getHunHuanMap());
        for (DouLuoDaLuEnemyTip tip : tipList) {
            DouLuoDaLuProto.DouLuoDaLuDeathInfo.Builder tipBuilder = DouLuoDaLuProto.DouLuoDaLuDeathInfo.newBuilder();
            tipBuilder.setLose(tip.getRobedProperty());
            tipBuilder.setDamage(tip.getDamage());
            DouLuoDaLuUserData tipUser = context.getActivity().getAllUserMap().get(tip.getEnemyId());
            if(tipUser != null){
                tipBuilder.setAttackerName(tipUser.getUserBaseInfo().getNickName());
                tipBuilder.setAttackerServerId(tipUser.getServerId());
            }
            tipBuilder.setRegionId(tip.getRegionId());
            tipBuilder.setAttackType(tip.getAttackType());
            tempBuilder.addDeath(tipBuilder);
        }
        context.getActivity().pushMsg(enemyUserData.getServerId(), tempBuilder);
    }

    /**
     * （森林）,防守日志同步给区服
     */
    public static void notifyUserBeFight(DouLuoDaLuUserData attackUser, DouLuoDaLuUserData targetUser, long damage, long blood, int fightType, String lose){
        //通知被打
        DouLuoDaLuProto.DouLuoDaLuEventBattleNotifySyncMsg.Builder notifyBuilder = DouLuoDaLuProto.DouLuoDaLuEventBattleNotifySyncMsg.newBuilder();
        notifyBuilder.setActivityId(attackUser.getActivityId());
        DouLuoDaLuProto.DouLuoDaLuEventBattleNotifyTemp.Builder tempBuilder = DouLuoDaLuProto.DouLuoDaLuEventBattleNotifyTemp.newBuilder();
        tempBuilder.setUserId(targetUser.getUserId());
        tempBuilder.setEnemyUserId(attackUser.getUserId());
        tempBuilder.setPlayerInfo(PlayerBasePb.parsePlayerBaseTempMsg(attackUser.getUserBaseInfo()));
        tempBuilder.setDamage(damage);
        tempBuilder.setBlood(blood);
        tempBuilder.setType(fightType);
        tempBuilder.setLogTime(System.currentTimeMillis());
        if(!StringUtils.isNullOrEmpty(lose)){
            tempBuilder.setLose(lose);
        }else {
            tempBuilder.setLose("");
        }
        notifyBuilder.setNotify(tempBuilder);
        MessageHelper.sendPacket(targetUser.getServerId(), targetUser.getUserId(), YanQuMessageUtils.buildMessage(Protocol.S_DOU_LUO_DA_LU_EVENT_BATTLE_NOTIFY_SYNC, notifyBuilder));
    }

    /**
     * 是否有万年以上魂环
     */
    public static boolean containHunHuan(Property hunHuan, int year) {
        for (Map.Entry<Integer, BigInteger> entry : hunHuan.getGoods().entrySet()) {
            GoodsInfo goodsInfo = TempCommonMgr.getGoodsInfo(entry.getKey());
            if(goodsInfo == null){
                continue;
            }
            if(goodsInfo.getParamList().get(0).intValue() >= year){
                return true;
            }
        }
        return false;
    }

    /**
     * 最后一个门客
     */
    private static DouLuoDaLuPatronsBattle getLast(List<DouLuoDaLuPatronsBattle> battleList) {
        if(battleList.size() > 0) {
            DouLuoDaLuPatronsBattle lastPatrons = battleList.get(battleList.size() - 1);
            return lastPatrons;
        }
        return null;
    }

    /**
     * 最后一个门客
     */
    private static DouLuoDaLuPatronsBattleEnemy getLastEnemy(List<DouLuoDaLuPatronsBattleEnemy> battleList) {
        if(battleList.size() > 0) {
            DouLuoDaLuPatronsBattleEnemy lastPatrons = battleList.get(battleList.size() - 1);
            return lastPatrons;
        }
        return null;
    }

    /**
     * 镜像门客能力
     * @param enemy 被镜像的玩家
     */
    private static DouLuoDaLuPatronsBattle getDouLuoDaLuPatronsBattle(CrossDouLouDaLuActivity contextActivity, DouLuoDaLuUserData enemy, DouLuoDaLuUserPatrons enemyPatrons) {
        DouLuoDaLuPatronsBattle battlePatrons = new DouLuoDaLuPatronsBattle();
        List<Integer> buffIdList = contextActivity.mergeHunHuan(enemy);
        battlePatrons.setAbility(enemyPatrons.getAbility());
        //固定值加成
        int addition = contextActivity.getHunLiFixedAddition(buffIdList);
        //千分比加成
        int permillage = contextActivity.getHunLiMilliAddition(buffIdList);
        long hunLi = contextActivity.calHunLi(battlePatrons.getAbility(), addition, permillage);
        battlePatrons.setHunLi(hunLi);
        battlePatrons.setBlood(hunLi);
        battlePatrons.setTotalBlood(hunLi);
        battlePatrons.setAddition(addition);
        battlePatrons.setAddition2(permillage);
        battlePatrons.setPatronsId(enemyPatrons.getPatronsId());
        battlePatrons.setPatronsLv(enemyPatrons.getPatronsLv());
        return battlePatrons;
    }

    /**
     * 镜像所有对方门客
     */
    private static List<DouLuoDaLuPatronsBattleEnemy> getDouLuoDaLuAllPatronsBattle(CrossDouLouDaLuActivity contextActivity, DouLuoDaLuUserData enemy) {
        List<Integer> buffIdList = contextActivity.mergeHunHuan(enemy);
        //固定值加成
        int addition = contextActivity.getHunLiFixedAddition(buffIdList);
        //千分比加成
        int permillage = contextActivity.getHunLiMilliAddition(buffIdList);
        List<DouLuoDaLuPatronsBattleEnemy> result = new ArrayList<>();
        for (Map.Entry<Integer, DouLuoDaLuUserPatrons> patronsEntry : enemy.getPatronsMap().entrySet()) {
            DouLuoDaLuUserPatrons enemyPatrons = patronsEntry.getValue();
            DouLuoDaLuPatronsBattleEnemy battlePatrons = new DouLuoDaLuPatronsBattleEnemy();
            battlePatrons.setAbility(enemyPatrons.getAbility());
            battlePatrons.setHunLi(enemyPatrons.getHunLi());
            long hunLi = contextActivity.calHunLi(battlePatrons.getAbility(), addition, permillage);
            battlePatrons.setHunLi(hunLi);
            battlePatrons.setBlood(hunLi);
            battlePatrons.setTotalBlood(hunLi);
            battlePatrons.setAddition(addition);
            battlePatrons.setAddition2(permillage);
            battlePatrons.setPatronsId(enemyPatrons.getPatronsId());
            battlePatrons.setPatronsLv(enemyPatrons.getPatronsLv());
            battlePatrons.setSkinId(enemyPatrons.getSkinId());
            battlePatrons.setPromotionId(enemyPatrons.getPromotionId());
            battlePatrons.setStageLv(enemyPatrons.getStageLv());
            result.add(battlePatrons);
        }
        return result;
    }


    /**
     * 构建门客信息PB（展示）
     */
    public static DouLuoDaLuProto.DouLuoDaLuPatronsDetailTemp.Builder parseDouLuoDaLuPatronsDetailTemp(DouLuoDaLuUserPatrons userPatrons){
        DouLuoDaLuProto.DouLuoDaLuPatronsDetailTemp.Builder builder = DouLuoDaLuProto.DouLuoDaLuPatronsDetailTemp.newBuilder();
        builder.setAbility(userPatrons.getHunLi());
        builder.setPatronsId(userPatrons.getPatronsId());
        builder.setPatronsLv(userPatrons.getPatronsLv());
        builder.setPromotionId(userPatrons.getPromotionId());
        builder.setSkinId(userPatrons.getSkinId());
        return builder;
    }

    /**
     * 构建我方门客战斗数据PB
     */
    public static DouLuoDaLuProto.DouLuoDaLuPatronsBattleDataTemp.Builder buildPatronsBattleData(DouLuoDaLuPatronsBattle patronsBattle){
        DouLuoDaLuProto.DouLuoDaLuPatronsBattleDataTemp.Builder builder = DouLuoDaLuProto.DouLuoDaLuPatronsBattleDataTemp.newBuilder();
        builder.setPatronsId(patronsBattle.getPatronsId());
        builder.setPatronsLv(patronsBattle.getPatronsLv());
        builder.setSkinId(patronsBattle.getSkinId());
        builder.setPromotionId(patronsBattle.getPromotionId());
        builder.setAbility(patronsBattle.getAbility());
        builder.setTotalBlood(patronsBattle.getTotalBlood());
        builder.setBlood(patronsBattle.getBlood());
        builder.setStageLv(patronsBattle.getStageLv());
        builder.setBuyBuffIdx(patronsBattle.getBuyBuffIdx());
        builder.addAllBuff(patronsBattle.getBuffList());
        builder.setWinTimes(patronsBattle.getTimes());
        builder.setRewards(patronsBattle.isWinRewards());
        builder.setGiveUpFirst(patronsBattle.isGiveUpFirst());
        builder.setHunLi(patronsBattle.getHunLi());
        return builder;
    }

    /**
     * 构建对手门客战斗数据PB
     */
    public static DouLuoDaLuProto.DouLuoDaLuPatronsBattleDataTemp.Builder buildPatronsBattleData(DouLuoDaLuPatronsBattleEnemy patronsBattle){
        DouLuoDaLuProto.DouLuoDaLuPatronsBattleDataTemp.Builder builder = DouLuoDaLuProto.DouLuoDaLuPatronsBattleDataTemp.newBuilder();
        builder.setPatronsId(patronsBattle.getPatronsId());
        builder.setPatronsLv(patronsBattle.getPatronsLv());
        builder.setSkinId(patronsBattle.getSkinId());
        builder.setPromotionId(patronsBattle.getPromotionId());
        builder.setAbility(patronsBattle.getAbility());
        builder.setTotalBlood(patronsBattle.getTotalBlood());
        builder.setBlood(patronsBattle.getBlood());
        builder.setStageLv(patronsBattle.getStageLv());
        builder.setHunLi(patronsBattle.getHunLi());
        return builder;
    }

    /**
     * 构建协助记录PB
     */
    private static DouLuoDaLuProto.DouLuoDaLuHelpRecordEntity.Builder buildHelpRecord(CrossDouLuoDaLuContext context, DouLuoDaLuHelpRecordData item) {
        DouLuoDaLuProto.DouLuoDaLuHelpRecordEntity.Builder builder = DouLuoDaLuProto.DouLuoDaLuHelpRecordEntity.newBuilder();
        builder.setId(item.getId());
        DouLuoDaLuUserData friend = context.getActivity().getAllUserMap().get(item.getUserId());
        builder.setHelpId(friend.getUserId());
        builder.setHelpUserName(friend.getUserBaseInfo().getNickName());
        builder.setHelpServerId(friend.getUserBaseInfo().getServerId());
        builder.setTotalBlood(item.getTargetTotalBlood());
        builder.setRegionId(item.getRegionId());
        builder.setEventId(item.getEventId());
        builder.setBlood(item.getTargetBlood());
        builder.setMonsterId((int)item.getTargetId());
        if(context.getUserData().getUserId() == item.getUserId() && !item.isReceived() && item.getKilledUserId() > 0){
            builder.setHasReward(true);
        }
        builder.setRecordTime(item.getRecordTime());
        if(context.getActivity().getConfig().getPlayerEventId().contains(item.getEventId())){
            DouLuoDaLuUserData targetUser =  context.getActivity().getAllUserMap().get(item.getTargetId());
            if(targetUser != null){
                builder.setTargetInfo(PlayerBasePb.parsePlayerBaseTempMsg(targetUser.getUserBaseInfo()));
            }
        }else {

        }

        DouLuoDaLuAttackInfo attackInfo = item.getHelpAttackMap().get(context.getUserId());
        if(attackInfo != null){
            builder.setLastAttackTime(attackInfo.getAttackTime());
        }
        for (Map.Entry<Long, DouLuoDaLuAttackInfo> entry : item.getHelpAttackMap().entrySet()) {
            if(entry.getKey() == item.getUserId()){
                continue;
            }
            DouLuoDaLuUserData daLuUserData = context.getActivity().getAllUserMap().get(entry.getKey());
            if(daLuUserData != null){
                builder.addHelpAttackNameList(daLuUserData.getUserBaseInfo().getNickName());
            }
        }
        return builder;
    }

    /**
     * 构建队伍PB
     */
    public static DouLuoDaLuProto.DouLuoDaLuTeamEntity.Builder buildTeamEntity(CrossDouLouDaLuActivity activity, DouLuoDaLuTeamData team, boolean showApplyList){
        DouLuoDaLuProto.DouLuoDaLuTeamEntity.Builder builder = DouLuoDaLuProto.DouLuoDaLuTeamEntity.newBuilder();
        builder.setTeamId(team.getTeamId());
        builder.setTeamName(team.getName());
        builder.setLeaderId(team.getCaptainId());
        builder.setLeaderServerId(team.getCaptainServerId());

        DouLuoDaLuUserData userData = activity.getAllUserMap().get(team.getCaptainId());
        if(userData != null){
            builder.setLeaderName(userData.getUserBaseInfo().getNickName());
        }
        long allEarn = 0;
        for (Map.Entry<Long, Long> entry : team.getMemberList().entrySet()) {
            DouLuoDaLuProto.DouLuoDaLuMemberEntity.Builder  memberBuilder = builderMemberEntity(activity, entry.getKey());
            if(memberBuilder != null){
                builder.addMembers(memberBuilder);
                allEarn += memberBuilder.getHunLi();
            }
        }
        builder.setSumEarn(allEarn);
        builder.setCreateTime(team.getCreateTime());
        if(showApplyList){
            for (Map.Entry<Long, Long> entry : team.getApplyList().entrySet()) {
                DouLuoDaLuUserData  applicant = activity.getAllUserMap().get(entry.getKey());
                if(applicant != null){
                    builder.addApplyList(buildTeamApplyUserEntity(applicant, entry.getValue()));
                }
            }
        }
        //队伍排行
        builder.setRank(getTeamRank(activity, team));
        return builder;
    }

    /**
     * 构建队伍申请PB
     */
    public static DouLuoDaLuProto.DouLuoDaLuApplyUserEntity.Builder buildTeamApplyUserEntity(DouLuoDaLuUserData userData, long time){
        DouLuoDaLuProto.DouLuoDaLuApplyUserEntity.Builder builder = DouLuoDaLuProto.DouLuoDaLuApplyUserEntity.newBuilder();
        builder.setUserId(userData.getUserId());
        builder.setAllPatronsEarn(userData.getAllPatronsEarn());
        builder.setApplyTime(time);
        builder.setPlayerInfo(PlayerBasePb.parsePlayerBaseTempMsg(userData.getUserBaseInfo()));
        return builder;
    }

    /**
     * 构建队伍成员PB
     */
    public static DouLuoDaLuProto.DouLuoDaLuMemberEntity.Builder builderMemberEntity(CrossDouLouDaLuActivity activity, long userId){
        DouLuoDaLuUserData userData = activity.getAllUserMap().get(userId);
        if(userData == null){
            return null;
        }
        DouLuoDaLuProto.DouLuoDaLuMemberEntity.Builder builder = DouLuoDaLuProto.DouLuoDaLuMemberEntity.newBuilder();
        builder.setUserId(userId);
        builder.setMemberInfo(PlayerBasePb.parsePlayerBaseTempMsg(userData.getUserBaseInfo()));
        builder.setRegionId(userData.getRegionId());
        builder.setAllScore(userData.getScore());
        builder.setRank(getUserRank(activity, userData, eGamePlayerEventType.DouLuoDaLuPhaseOneUserScoreCrossRank.getValue()));
        builder.setServerId(userData.getServerId());
        builder.setHunLi(userData.getHunLi());
        if(userData.getBattleData() != null){
            builder.setAllScore2(userData.getBattleData().getScore());
        }else {
            builder.setAllScore2(0);
        }
        builder.setRank2(getUserRank(activity, userData, eGamePlayerEventType.DouLuoDaLuPhaseTwoUserScoreCrossRank.getValue()));
        return builder;
    }

    /**
     * 构建队伍申请变更PB
     */
    public static DouLuoDaLuProto.DouLuoDaLuApplyChangeEntity.Builder buildApplyChangeEntity(int type, DouLuoDaLuProto.DouLuoDaLuApplyUserEntity.Builder applyInfo, Long userId){
        DouLuoDaLuProto.DouLuoDaLuApplyChangeEntity.Builder builder = DouLuoDaLuProto.DouLuoDaLuApplyChangeEntity.newBuilder();
        builder.setType(type);
        if(type == 0){
            builder.setJoinInfo(applyInfo);
        }else if(type == 1){
            builder.setUserId(userId);
        }
        return builder;
    }

    /**
     * 构建队伍离队信息PB
     */
    public static DouLuoDaLuProto.DouLuoDaLuLeaveInfoEntity.Builder buildLeaveInfoEntity(CrossDouLouDaLuActivity activityInfo, DouLuoDaLuUserData userData){
        DouLuoDaLuProto.DouLuoDaLuLeaveInfoEntity.Builder builder = DouLuoDaLuProto.DouLuoDaLuLeaveInfoEntity.newBuilder();
        builder.setType(userData.getLeaveTip().getLeaveStatus());
        builder.setTeamName(userData.getLeaveTip().getLeaveTeamName());
        DouLuoDaLuUserData oldLeader = activityInfo.getAllUserMap().get(userData.getLeaveTip().getLeaveLeaderId());
        builder.setLeaderName(oldLeader.getUserBaseInfo().getNickName());
        builder.setLeaderServerId(oldLeader.getServerId());
        return builder;
    }

    /**
     * 构建仇人PB
     */
    public static DouLuoDaLuProto.DouLuoDaLuEnemyEntity.Builder buildEnemyEntity(CrossDouLouDaLuActivity activity, DouLuoDaLuEnemyTip enemyTip){
        DouLuoDaLuProto.DouLuoDaLuEnemyEntity.Builder builder = DouLuoDaLuProto.DouLuoDaLuEnemyEntity.newBuilder();
        DouLuoDaLuUserData enemy = activity.getAllUserMap().get(enemyTip.getEnemyId());
        builder.setEnemyName(enemy.getUserBaseInfo().getNickName());
        builder.setEnemyServerId(enemy.getServerId());
        builder.setDamage(enemyTip.getDamage());
        builder.setLose(enemyTip.getRobedProperty());
        builder.setRegionId(enemyTip.getRegionId());
        builder.setAttackType(enemyTip.getAttackType());
        return builder;
    }


    public static void repair(int activityId, int type, int groupId) {
        getLogger().info("activity {} repair", activityId);
        CrossDouLouDaLuActivity activity = getActivityOrNull(activityId, groupId);
        if (activity == null) {
            getLogger().error("activityId {} is null", activityId);
            return;
        }
        if (type == 1) {
            ActivityInfo activityInfo = ActivityMgr.getActivityInfo(activityId);
            if (activityInfo == null) {
                getLogger().error("activityId {} is null", activityId);
                return;
            }
            //重载配置
            activity.initConfig(activityInfo);
            getLogger().info("activity {} reload", activityId);
        }
    }

    public boolean removeExpireData() {
        List<Integer> acList = new ArrayList<>();
        long nowTime = System.currentTimeMillis();
        for (DouLuoActivityGroup activityGroup : activityGroupMap.values()) {
            int activityId = activityGroup.getActivityId();
            ActivityInfo activityInfo = CrossDouLuoDaLuActivityMgr.getActivityInfo(activityId);
            if (activityInfo == null) {
                acList.add(activityId);
                continue;
            }
            if ((nowTime > activityInfo.getEndShowTime() * 1000 + 3 * 24 * 3600 * 1000)) {
                acList.add(activityInfo.getActivityId());
            }
        }


        for (Integer activityId : acList) {
            activityGroupMap.remove(activityId);
        }
        return true;
    }

    public static String getUserActivityUnionUid(int activityId, long userId) {
        return Cross2UnionActivityGroupMgr.getUnionUid(activityId, userId);
    }
}
